From 2d1311e01e742932d459f46068a1aec61000dc77 Mon Sep 17 00:00:00 2001 From: njajkes Date: Tue, 28 Mar 2023 12:24:53 +0300 Subject: [PATCH 1/3] chore: added event bridgel1 test --- contracts/test/L1BridgeRouter.test.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/contracts/test/L1BridgeRouter.test.js b/contracts/test/L1BridgeRouter.test.js index f4796d9..2946b28 100644 --- a/contracts/test/L1BridgeRouter.test.js +++ b/contracts/test/L1BridgeRouter.test.js @@ -19,15 +19,24 @@ describe("L1BridgeRouter", () => { expect(await this.bridge.token()).eq(this.token.address); }); - describe("Bridge to L2", () => { - beforeEach(async () => { - await this.token.approve(this.bridge.address, TOKEN_ID); - await this.bridge.bridgeToL2(L2_NETWORK_ID, TOKEN_ID); - }); + describe("Bridge to L2", () => { + let bridgeTx; - it("token got withdrawn to BridgeRouter", async () => { - expect(await this.token.ownerOf(TOKEN_ID)).eq(this.bridge.address); - }); + beforeEach(async () => { + await this.token.approve(this.bridge.address, TOKEN_ID); + bridgeTx = await this.bridge.bridgeToL2(L2_NETWORK_ID, TOKEN_ID); + }); + + it("token got withdrawn to BridgeRouter", async () => { + expect(await this.token.ownerOf(TOKEN_ID)).eq(this.bridge.address); + }); + + it("should call event BridgeToL2", async () => { + await expect(bridgeTx) + .to + .emit(this.bridge, "BridgeToL2") + .withArgs(this.deployer.address, L2_NETWORK_ID, 1); + }) describe("Unbridge back from L2", () => { beforeEach(async () => { From ad327f7e7e21eeb1b63550ee114d1e3011836dd2 Mon Sep 17 00:00:00 2001 From: Vadim Volkov Date: Mon, 3 Apr 2023 18:07:05 +0400 Subject: [PATCH 2/3] chore: added tests, fixed configs, added/fixed contracts HACK-6, HACK-8 --- .../contracts/{ExampleNFT.sol => L1Token.sol} | 16 ++------- contracts/contracts/L2Token.sol | 30 ++++++++++++++++ contracts/test/ExampleNFT.test.js | 14 -------- contracts/test/L1BridgeRouter.test.js | 4 +-- contracts/test/L1Token.test.js | 25 ++++++++++++++ contracts/test/L2Token.test.js | 34 +++++++++++++++++++ project_data.py | 3 +- 7 files changed, 94 insertions(+), 32 deletions(-) rename contracts/contracts/{ExampleNFT.sol => L1Token.sol} (60%) create mode 100644 contracts/contracts/L2Token.sol delete mode 100644 contracts/test/ExampleNFT.test.js create mode 100644 contracts/test/L1Token.test.js create mode 100644 contracts/test/L2Token.test.js diff --git a/contracts/contracts/ExampleNFT.sol b/contracts/contracts/L1Token.sol similarity index 60% rename from contracts/contracts/ExampleNFT.sol rename to contracts/contracts/L1Token.sol index 94ec8c9..ecab55b 100644 --- a/contracts/contracts/ExampleNFT.sol +++ b/contracts/contracts/L1Token.sol @@ -2,31 +2,19 @@ pragma solidity ^0.8.18; -import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; /** * @title L1Token * @author OnGrid Dev Team **/ -contract ExampleNFT is ERC721Enumerable, AccessControl { +contract L1Token is ERC721Enumerable, Ownable { using Strings for uint256; constructor() ERC721("Grizzly", "GRZL") {} - function supportsInterface( - bytes4 interfaceId - ) - public - view - virtual - override(ERC721Enumerable, AccessControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - /** * @dev Mints a specific to the given address * @param to the receiver diff --git a/contracts/contracts/L2Token.sol b/contracts/contracts/L2Token.sol new file mode 100644 index 0000000..74910f7 --- /dev/null +++ b/contracts/contracts/L2Token.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.18; + +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; + +/** + * @title L1Token + * @author OnGrid Dev Team + **/ +contract L2Token is ERC721Enumerable, Ownable { + using Strings for uint256; + + constructor() ERC721("BridgedGrizzly", "BRGRZL") {} + + /** + * @dev Mints a specific to the given address + * @param to the receiver + */ + function mint(address to) public { + uint256 mintIndex = totalSupply(); + _safeMint(to, mintIndex); + } + + function burn(uint256 id) public { + _burn(id); + } +} diff --git a/contracts/test/ExampleNFT.test.js b/contracts/test/ExampleNFT.test.js deleted file mode 100644 index ed2624b..0000000 --- a/contracts/test/ExampleNFT.test.js +++ /dev/null @@ -1,14 +0,0 @@ -const { ethers } = require("hardhat"); -const { expect } = require("chai"); - -describe("ExampleNFT", () => { - before(async () => { - this.factory = await ethers.getContractFactory("ExampleNFT"); - this.contract = await this.factory.deploy(); - }); - - it("should give me token name", async () => { - const name = await this.contract.name(); - expect(name).eq("Grizzly"); - }); -}); diff --git a/contracts/test/L1BridgeRouter.test.js b/contracts/test/L1BridgeRouter.test.js index 2946b28..8e2178f 100644 --- a/contracts/test/L1BridgeRouter.test.js +++ b/contracts/test/L1BridgeRouter.test.js @@ -8,7 +8,7 @@ describe("L1BridgeRouter", () => { beforeEach(async () => { this.signers = await ethers.getSigners(); this.deployer = this.signers[0]; - this.tokenFactory = await ethers.getContractFactory("ExampleNFT"); + this.tokenFactory = await ethers.getContractFactory("L1Token"); this.token = await this.tokenFactory.deploy(); this.bridgeFactory = await ethers.getContractFactory("L1BridgeRouter"); this.bridge = await this.bridgeFactory.deploy(this.token.address); @@ -35,7 +35,7 @@ describe("L1BridgeRouter", () => { await expect(bridgeTx) .to .emit(this.bridge, "BridgeToL2") - .withArgs(this.deployer.address, L2_NETWORK_ID, 1); + .withArgs(this.deployer.address, L2_NETWORK_ID, TOKEN_ID); }) describe("Unbridge back from L2", () => { diff --git a/contracts/test/L1Token.test.js b/contracts/test/L1Token.test.js new file mode 100644 index 0000000..a5565f2 --- /dev/null +++ b/contracts/test/L1Token.test.js @@ -0,0 +1,25 @@ +const { ethers } = require("hardhat"); +const {expect} = require("chai"); + +describe("L1Token", async () => { + before(async () => { + this.factory = await ethers.getContractFactory("L1Token"); + this.contract = await this.factory.deploy(); + this.signers = await ethers.getSigners(); + this.owner = this.signers[0]; + }); + + it("should give me token name", async () => { + const name = await this.contract.name(); + expect(name).eq("Grizzly"); + }); + + it("should mint a token", async () => { + const result = await this.contract.mint(this.owner.address); + let balance = await this.contract.balanceOf(this.owner.address); + let totalTokens = await this.contract.totalSupply(); + expect(balance).eq("1"); + expect(totalTokens).eq("1") + } + ) +}); diff --git a/contracts/test/L2Token.test.js b/contracts/test/L2Token.test.js new file mode 100644 index 0000000..998e89f --- /dev/null +++ b/contracts/test/L2Token.test.js @@ -0,0 +1,34 @@ +const { ethers } = require("hardhat"); +const {expect} = require("chai"); + +describe("L2Token", async () => { + before(async () => { + this.factory = await ethers.getContractFactory("L2Token"); + this.contract = await this.factory.deploy(); + this.signers = await ethers.getSigners(); + this.owner = this.signers[0]; + }); + + it("should mint a token", async () => { + const result = await this.contract.mint(this.owner.address); + let balance = await this.contract.balanceOf(this.owner.address); + let totalTokens = await this.contract.totalSupply(); + expect(balance).eq("1"); + expect(totalTokens).eq("1") + } + ); + + it("should burn a token", async () => { + const result = await this.contract.mint(this.owner.address); + let balance = await this.contract.balanceOf(this.owner.address); + let totalTokens = await this.contract.totalSupply(); + expect(balance).eq("2"); + expect(totalTokens).eq("2") + await this.contract.burn(result.value); + balance = await this.contract.balanceOf(this.owner.address); + totalTokens = await this.contract.totalSupply(); + expect(balance).eq("1"); + expect(totalTokens).eq("1") + } + ) +}); diff --git a/project_data.py b/project_data.py index 20c100a..95f3a48 100644 --- a/project_data.py +++ b/project_data.py @@ -1,11 +1,10 @@ import os -LANGS = ["Python", "Solidity", "Javascript", "Typescript"] +LANGS = ["Python", "Solidity", "JavaScript", "TypeScript"] DIRS = [ "api", "app", "contracts", - "ingress", "polybase_integration" ] EXCLUDED_DIRS = [ From fe7cfc94a50b45ac783b8ba9862417830bada17c Mon Sep 17 00:00:00 2001 From: Vadim Volkov Date: Tue, 4 Apr 2023 17:44:37 +0400 Subject: [PATCH 3/3] chore: wrote a minter, fixed the reference to (formerly) ExampleNFT HACK-6 --- contracts/contracts/L2Token.sol | 15 +- contracts/contracts/L2TokenMinter.sol | 24 + contracts/deploy/L1BridgeRouter.js | 3 +- .../deploy/{ExampleNFT.js => L1Token.js} | 4 +- contracts/deploy/L2Token.js | 12 + contracts/deploy/L2TokenMinter.js | 10 + .../{mintExampleNFTs.js => mintL1NFTs.js} | 8 +- .../deployments/goerli/L1BridgeRouter.json | 36 +- contracts/deployments/goerli/L1Token.json | 747 +++++++++++++++++ contracts/deployments/goerli/L2Token.json | 782 ++++++++++++++++++ .../deployments/goerli/L2TokenMinter.json | 95 +++ 11 files changed, 1707 insertions(+), 29 deletions(-) create mode 100644 contracts/contracts/L2TokenMinter.sol rename contracts/deploy/{ExampleNFT.js => L1Token.js} (74%) create mode 100644 contracts/deploy/L2Token.js create mode 100644 contracts/deploy/L2TokenMinter.js rename contracts/deploy/{mintExampleNFTs.js => mintL1NFTs.js} (54%) create mode 100644 contracts/deployments/goerli/L1Token.json create mode 100644 contracts/deployments/goerli/L2Token.json create mode 100644 contracts/deployments/goerli/L2TokenMinter.json diff --git a/contracts/contracts/L2Token.sol b/contracts/contracts/L2Token.sol index 74910f7..dc2a99d 100644 --- a/contracts/contracts/L2Token.sol +++ b/contracts/contracts/L2Token.sol @@ -5,26 +5,33 @@ pragma solidity ^0.8.18; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; +import "./L2TokenMinter.sol"; /** - * @title L1Token + * @title L2Token * @author OnGrid Dev Team **/ contract L2Token is ERC721Enumerable, Ownable { using Strings for uint256; - constructor() ERC721("BridgedGrizzly", "BRGRZL") {} + constructor( + L2TokenMinter minter + ) ERC721("Grizzly", "GRZL") { + transferOwnership(address(minter)); + L2TokenMinter a = L2TokenMinter(address(minter)); + a.setOwnedContract(address(this)); + } /** * @dev Mints a specific to the given address * @param to the receiver */ - function mint(address to) public { + function mint(address to) public onlyOwner { uint256 mintIndex = totalSupply(); _safeMint(to, mintIndex); } - function burn(uint256 id) public { + function burn(uint256 id) public onlyOwner { _burn(id); } } diff --git a/contracts/contracts/L2TokenMinter.sol b/contracts/contracts/L2TokenMinter.sol new file mode 100644 index 0000000..7edb6fd --- /dev/null +++ b/contracts/contracts/L2TokenMinter.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.18; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "./L2Token.sol"; + +contract L2TokenMinter { + address ownedContract; + address owner; + + constructor () { + owner = msg.sender; + } + + function setOwnedContract (address owned) public { + ownedContract = owned; + } + + function mintL2 (address to) public { + L2Token proxied = L2Token(ownedContract); + proxied.mint(to); + } +} \ No newline at end of file diff --git a/contracts/deploy/L1BridgeRouter.js b/contracts/deploy/L1BridgeRouter.js index 4046033..0e27c09 100644 --- a/contracts/deploy/L1BridgeRouter.js +++ b/contracts/deploy/L1BridgeRouter.js @@ -1,7 +1,7 @@ module.exports = async ({ getNamedAccounts, deployments }) => { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const tokenAddress = (await deployments.get("ExampleNFT")).address; + const tokenAddress = (await deployments.get("L1Token")).address; await deploy("L1BridgeRouter", { from: deployer, args: [tokenAddress], @@ -9,3 +9,4 @@ module.exports = async ({ getNamedAccounts, deployments }) => { }); }; module.exports.tags = ["L1BridgeRouter"]; +module.exports.dependencies = ["L1Token"] diff --git a/contracts/deploy/ExampleNFT.js b/contracts/deploy/L1Token.js similarity index 74% rename from contracts/deploy/ExampleNFT.js rename to contracts/deploy/L1Token.js index d96435c..9d326c4 100644 --- a/contracts/deploy/ExampleNFT.js +++ b/contracts/deploy/L1Token.js @@ -1,10 +1,10 @@ module.exports = async ({ getNamedAccounts, deployments }) => { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - await deploy("ExampleNFT", { + await deploy("L1Token", { from: deployer, args: [], log: true, }); }; -module.exports.tags = ["ExampleNFT"]; +module.exports.tags = ["L1Token"]; diff --git a/contracts/deploy/L2Token.js b/contracts/deploy/L2Token.js new file mode 100644 index 0000000..8ebd67f --- /dev/null +++ b/contracts/deploy/L2Token.js @@ -0,0 +1,12 @@ +module.exports = async ({ getNamedAccounts, deployments }) => { + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + const tokenAddress = (await deployments.get("L2TokenMinter")).address; + await deploy("L2Token", { + from: deployer, + args: [tokenAddress], + log: true, + }); + }; +module.exports.tags = ["L2Token"]; +module.exports.dependencies = ["L2TokenMinter"] \ No newline at end of file diff --git a/contracts/deploy/L2TokenMinter.js b/contracts/deploy/L2TokenMinter.js new file mode 100644 index 0000000..94959e6 --- /dev/null +++ b/contracts/deploy/L2TokenMinter.js @@ -0,0 +1,10 @@ +module.exports = async ({ getNamedAccounts, deployments }) => { + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + await deploy("L2TokenMinter", { + from: deployer, + args: [], + log: true, + }); + }; + module.exports.tags = ["L2TokenMinter"]; diff --git a/contracts/deploy/mintExampleNFTs.js b/contracts/deploy/mintL1NFTs.js similarity index 54% rename from contracts/deploy/mintExampleNFTs.js rename to contracts/deploy/mintL1NFTs.js index 32f30cd..a16cb99 100644 --- a/contracts/deploy/mintExampleNFTs.js +++ b/contracts/deploy/mintL1NFTs.js @@ -1,12 +1,12 @@ module.exports = async ({ deployments }) => { const hre = require("hardhat"); const ethers = hre.ethers; - const address = (await deployments.get("ExampleNFT")).address; - const Contract = await ethers.getContractFactory("ExampleNFT"); + const address = (await deployments.get("L1Token")).address; + const Contract = await ethers.getContractFactory("L1Token"); const contract = Contract.attach(address); for (var i = 1; i <= 1; i++) { console.log(await contract.mint(process.env.DEPLOYER_WALLET)); } }; -module.exports.tags = ["mintExampleNFTs"]; -module.exports.dependencies = ["ExampleNFT"]; +module.exports.tags = ["mintL1NFTs"]; +module.exports.dependencies = ["L1Token"]; diff --git a/contracts/deployments/goerli/L1BridgeRouter.json b/contracts/deployments/goerli/L1BridgeRouter.json index 016c223..ecdf00e 100644 --- a/contracts/deployments/goerli/L1BridgeRouter.json +++ b/contracts/deployments/goerli/L1BridgeRouter.json @@ -1,5 +1,5 @@ { - "address": "0xFe9ae2907dCdED590a4f38f5A9b3De2EbD8C9249", + "address": "0xA914e59c47e2c6e5DBd4489Bf4271fE099428422", "abi": [ { "inputs": [ @@ -121,30 +121,30 @@ "type": "function" } ], - "transactionHash": "0xdf4b2f25720643081718d1ff14a75498ba95cbba51d4867f732419b490550fb5", + "transactionHash": "0x3cf1605f03a43b4008bbf8c98718e843f925300772af9ae68bac45a3f725d6dd", "receipt": { "to": null, "from": "0x8289275310690BD0409cF12087F9D504cA24c4D1", - "contractAddress": "0xFe9ae2907dCdED590a4f38f5A9b3De2EbD8C9249", - "transactionIndex": 32, - "gasUsed": "414393", + "contractAddress": "0xA914e59c47e2c6e5DBd4489Bf4271fE099428422", + "transactionIndex": 45, + "gasUsed": "414381", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8bb5ad74e3e6cac93608e92fe730a01989d824bd555bc262058f7a311c8282c8", - "transactionHash": "0xdf4b2f25720643081718d1ff14a75498ba95cbba51d4867f732419b490550fb5", + "blockHash": "0x5fe796cd207a2fa94b04fe5d5d4d8f3919b037cfaac9ce37d573e5d6ad331373", + "transactionHash": "0x3cf1605f03a43b4008bbf8c98718e843f925300772af9ae68bac45a3f725d6dd", "logs": [], - "blockNumber": 8703138, - "cumulativeGasUsed": "2990502", + "blockNumber": 8772384, + "cumulativeGasUsed": "7598351", "status": 1, "byzantium": true }, "args": [ - "0xD0aF11B17499baA91849512B41d8C12C8C2D5a35" + "0xF24cEe7c2e89bbee3620A926fe3Fa9eDDC395402" ], - "numDeployments": 1, - "solcInputHash": "0d25b9ed61156364b0e252fcaf00dbbe", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC721\",\"name\":\"_token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"networkId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"BridgeToL2\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_networkId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bridgeToL2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC721\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"unbridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"OnGrid Dev Team*\",\"kind\":\"dev\",\"methods\":{\"bridgeToL2(uint256,uint256)\":{\"details\":\"Withdraws NFT to replicate it on L2 side\",\"params\":{\"_networkId\":\"destination L2 network\",\"_tokenId\":\"token id to bridge\"}},\"unbridge(uint256,address)\":{\"details\":\"Returns NFT back when bridging from L2 to L1\",\"params\":{\"_to\":\"destination address\",\"_tokenId\":\"token id to unbridge\"}}},\"title\":\"L1BridgeRouter\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1BridgeRouter.sol\":\"L1BridgeRouter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\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\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/L1BridgeRouter.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/**\\n * @title L1BridgeRouter\\n * @author OnGrid Dev Team\\n **/\\ncontract L1BridgeRouter is IERC721Receiver {\\n\\n IERC721 public token;\\n\\n event BridgeToL2(address from, uint256 networkId, uint256 tokenId);\\n\\n constructor(IERC721 _token) {\\n token = _token;\\n }\\n\\n /**\\n * @dev Withdraws NFT to replicate it on L2 side\\n * @param _networkId destination L2 network\\n * @param _tokenId token id to bridge\\n */\\n function bridgeToL2(uint256 _networkId, uint256 _tokenId) public {\\n // todo: check if _networkId supported. revert otherwise.\\n token.safeTransferFrom(msg.sender, address(this), _tokenId);\\n emit BridgeToL2(msg.sender, _networkId, _tokenId);\\n }\\n\\n /**\\n * @dev Returns NFT back when bridging from L2 to L1\\n * @param _tokenId token id to unbridge\\n * @param _to destination address\\n */\\n function unbridge(uint256 _tokenId, address _to) public {\\n token.safeTransferFrom(address(this), _to, _tokenId);\\n // todo: emit event\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) public override returns (bytes4) {\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xc5035e5f604bf9b76cefcc30333613998ce63a47a41375fdaaa46a41c2077a27\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610737380380610737833981810160405281019061003291906100ed565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061011a565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100a88261007d565b9050919050565b60006100ba8261009d565b9050919050565b6100ca816100af565b81146100d557600080fd5b50565b6000815190506100e7816100c1565b92915050565b60006020828403121561010357610102610078565b5b6000610111848285016100d8565b91505092915050565b61060e806101296000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302b47cb214610051578063150b7a021461006d578063553b5d9c1461009d578063fc0c546a146100b9575b600080fd5b61006b600480360381019061006691906102b1565b6100d7565b005b610087600480360381019061008291906103b4565b6101a5565b6040516100949190610477565b60405180910390f35b6100b760048036038101906100b29190610492565b6101ba565b005b6100c161024d565b6040516100ce9190610531565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b81526004016101349392919061056a565b600060405180830381600087803b15801561014e57600080fd5b505af1158015610162573d6000803e3d6000fd5b505050507f18be74c702ad73ecd2535e47f17075cd1e2c1e1d4ae17c34030c5ff47dfc3728338383604051610199939291906105a1565b60405180910390a15050565b600063150b7a0260e01b905095945050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b81526004016102179392919061056a565b600060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080fd5b600080fd5b6000819050919050565b61028e8161027b565b811461029957600080fd5b50565b6000813590506102ab81610285565b92915050565b600080604083850312156102c8576102c7610271565b5b60006102d68582860161029c565b92505060206102e78582860161029c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061031c826102f1565b9050919050565b61032c81610311565b811461033757600080fd5b50565b60008135905061034981610323565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126103745761037361034f565b5b8235905067ffffffffffffffff81111561039157610390610354565b5b6020830191508360018202830111156103ad576103ac610359565b5b9250929050565b6000806000806000608086880312156103d0576103cf610271565b5b60006103de8882890161033a565b95505060206103ef8882890161033a565b94505060406104008882890161029c565b935050606086013567ffffffffffffffff81111561042157610420610276565b5b61042d8882890161035e565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6104718161043c565b82525050565b600060208201905061048c6000830184610468565b92915050565b600080604083850312156104a9576104a8610271565b5b60006104b78582860161029c565b92505060206104c88582860161033a565b9150509250929050565b6000819050919050565b60006104f76104f26104ed846102f1565b6104d2565b6102f1565b9050919050565b6000610509826104dc565b9050919050565b600061051b826104fe565b9050919050565b61052b81610510565b82525050565b60006020820190506105466000830184610522565b92915050565b61055581610311565b82525050565b6105648161027b565b82525050565b600060608201905061057f600083018661054c565b61058c602083018561054c565b610599604083018461055b565b949350505050565b60006060820190506105b6600083018661054c565b6105c3602083018561055b565b6105d0604083018461055b565b94935050505056fea26469706673582212206ef7b6a13c0753451e4b72d1610d17cfa89539cd0526234e3920df72429ed74964736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806302b47cb214610051578063150b7a021461006d578063553b5d9c1461009d578063fc0c546a146100b9575b600080fd5b61006b600480360381019061006691906102b1565b6100d7565b005b610087600480360381019061008291906103b4565b6101a5565b6040516100949190610477565b60405180910390f35b6100b760048036038101906100b29190610492565b6101ba565b005b6100c161024d565b6040516100ce9190610531565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b81526004016101349392919061056a565b600060405180830381600087803b15801561014e57600080fd5b505af1158015610162573d6000803e3d6000fd5b505050507f18be74c702ad73ecd2535e47f17075cd1e2c1e1d4ae17c34030c5ff47dfc3728338383604051610199939291906105a1565b60405180910390a15050565b600063150b7a0260e01b905095945050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b81526004016102179392919061056a565b600060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080fd5b600080fd5b6000819050919050565b61028e8161027b565b811461029957600080fd5b50565b6000813590506102ab81610285565b92915050565b600080604083850312156102c8576102c7610271565b5b60006102d68582860161029c565b92505060206102e78582860161029c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061031c826102f1565b9050919050565b61032c81610311565b811461033757600080fd5b50565b60008135905061034981610323565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126103745761037361034f565b5b8235905067ffffffffffffffff81111561039157610390610354565b5b6020830191508360018202830111156103ad576103ac610359565b5b9250929050565b6000806000806000608086880312156103d0576103cf610271565b5b60006103de8882890161033a565b95505060206103ef8882890161033a565b94505060406104008882890161029c565b935050606086013567ffffffffffffffff81111561042157610420610276565b5b61042d8882890161035e565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6104718161043c565b82525050565b600060208201905061048c6000830184610468565b92915050565b600080604083850312156104a9576104a8610271565b5b60006104b78582860161029c565b92505060206104c88582860161033a565b9150509250929050565b6000819050919050565b60006104f76104f26104ed846102f1565b6104d2565b6102f1565b9050919050565b6000610509826104dc565b9050919050565b600061051b826104fe565b9050919050565b61052b81610510565b82525050565b60006020820190506105466000830184610522565b92915050565b61055581610311565b82525050565b6105648161027b565b82525050565b600060608201905061057f600083018661054c565b61058c602083018561054c565b610599604083018461055b565b949350505050565b60006060820190506105b6600083018661054c565b6105c3602083018561055b565b6105d0604083018461055b565b94935050505056fea26469706673582212206ef7b6a13c0753451e4b72d1610d17cfa89539cd0526234e3920df72429ed74964736f6c63430008120033", + "numDeployments": 2, + "solcInputHash": "d50704bd3b61e4d6e2bdbdcda49f3f62", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC721\",\"name\":\"_token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"networkId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"BridgeToL2\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_networkId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bridgeToL2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC721\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"unbridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"OnGrid Dev Team*\",\"kind\":\"dev\",\"methods\":{\"bridgeToL2(uint256,uint256)\":{\"details\":\"Withdraws NFT to replicate it on L2 side\",\"params\":{\"_networkId\":\"destination L2 network\",\"_tokenId\":\"token id to bridge\"}},\"unbridge(uint256,address)\":{\"details\":\"Returns NFT back when bridging from L2 to L1\",\"params\":{\"_to\":\"destination address\",\"_tokenId\":\"token id to unbridge\"}}},\"title\":\"L1BridgeRouter\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1BridgeRouter.sol\":\"L1BridgeRouter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\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\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/L1BridgeRouter.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/**\\n * @title L1BridgeRouter\\n * @author OnGrid Dev Team\\n **/\\ncontract L1BridgeRouter is IERC721Receiver {\\n IERC721 public token;\\n\\n event BridgeToL2(address from, uint256 networkId, uint256 tokenId);\\n\\n constructor(IERC721 _token) {\\n token = _token;\\n }\\n\\n /**\\n * @dev Withdraws NFT to replicate it on L2 side\\n * @param _networkId destination L2 network\\n * @param _tokenId token id to bridge\\n */\\n function bridgeToL2(uint256 _networkId, uint256 _tokenId) public {\\n // todo: check if _networkId supported. revert otherwise.\\n token.safeTransferFrom(msg.sender, address(this), _tokenId);\\n emit BridgeToL2(msg.sender, _networkId, _tokenId);\\n }\\n\\n /**\\n * @dev Returns NFT back when bridging from L2 to L1\\n * @param _tokenId token id to unbridge\\n * @param _to destination address\\n */\\n function unbridge(uint256 _tokenId, address _to) public {\\n token.safeTransferFrom(address(this), _to, _tokenId);\\n // todo: emit event\\n }\\n\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) public override returns (bytes4) {\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0x434d7280a1b63c6967eb6de593a783ee52943bb82066e34e72a5763b95faeb6d\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610737380380610737833981810160405281019061003291906100ed565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061011a565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100a88261007d565b9050919050565b60006100ba8261009d565b9050919050565b6100ca816100af565b81146100d557600080fd5b50565b6000815190506100e7816100c1565b92915050565b60006020828403121561010357610102610078565b5b6000610111848285016100d8565b91505092915050565b61060e806101296000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302b47cb214610051578063150b7a021461006d578063553b5d9c1461009d578063fc0c546a146100b9575b600080fd5b61006b600480360381019061006691906102b1565b6100d7565b005b610087600480360381019061008291906103b4565b6101a5565b6040516100949190610477565b60405180910390f35b6100b760048036038101906100b29190610492565b6101ba565b005b6100c161024d565b6040516100ce9190610531565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b81526004016101349392919061056a565b600060405180830381600087803b15801561014e57600080fd5b505af1158015610162573d6000803e3d6000fd5b505050507f18be74c702ad73ecd2535e47f17075cd1e2c1e1d4ae17c34030c5ff47dfc3728338383604051610199939291906105a1565b60405180910390a15050565b600063150b7a0260e01b905095945050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b81526004016102179392919061056a565b600060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080fd5b600080fd5b6000819050919050565b61028e8161027b565b811461029957600080fd5b50565b6000813590506102ab81610285565b92915050565b600080604083850312156102c8576102c7610271565b5b60006102d68582860161029c565b92505060206102e78582860161029c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061031c826102f1565b9050919050565b61032c81610311565b811461033757600080fd5b50565b60008135905061034981610323565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126103745761037361034f565b5b8235905067ffffffffffffffff81111561039157610390610354565b5b6020830191508360018202830111156103ad576103ac610359565b5b9250929050565b6000806000806000608086880312156103d0576103cf610271565b5b60006103de8882890161033a565b95505060206103ef8882890161033a565b94505060406104008882890161029c565b935050606086013567ffffffffffffffff81111561042157610420610276565b5b61042d8882890161035e565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6104718161043c565b82525050565b600060208201905061048c6000830184610468565b92915050565b600080604083850312156104a9576104a8610271565b5b60006104b78582860161029c565b92505060206104c88582860161033a565b9150509250929050565b6000819050919050565b60006104f76104f26104ed846102f1565b6104d2565b6102f1565b9050919050565b6000610509826104dc565b9050919050565b600061051b826104fe565b9050919050565b61052b81610510565b82525050565b60006020820190506105466000830184610522565b92915050565b61055581610311565b82525050565b6105648161027b565b82525050565b600060608201905061057f600083018661054c565b61058c602083018561054c565b610599604083018461055b565b949350505050565b60006060820190506105b6600083018661054c565b6105c3602083018561055b565b6105d0604083018461055b565b94935050505056fea2646970667358221220ffe5b1022325b0b50cd2f0aea5d0b9b60235c0cb25dbae9259d6c3b700b8888e64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806302b47cb214610051578063150b7a021461006d578063553b5d9c1461009d578063fc0c546a146100b9575b600080fd5b61006b600480360381019061006691906102b1565b6100d7565b005b610087600480360381019061008291906103b4565b6101a5565b6040516100949190610477565b60405180910390f35b6100b760048036038101906100b29190610492565b6101ba565b005b6100c161024d565b6040516100ce9190610531565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b81526004016101349392919061056a565b600060405180830381600087803b15801561014e57600080fd5b505af1158015610162573d6000803e3d6000fd5b505050507f18be74c702ad73ecd2535e47f17075cd1e2c1e1d4ae17c34030c5ff47dfc3728338383604051610199939291906105a1565b60405180910390a15050565b600063150b7a0260e01b905095945050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b81526004016102179392919061056a565b600060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080fd5b600080fd5b6000819050919050565b61028e8161027b565b811461029957600080fd5b50565b6000813590506102ab81610285565b92915050565b600080604083850312156102c8576102c7610271565b5b60006102d68582860161029c565b92505060206102e78582860161029c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061031c826102f1565b9050919050565b61032c81610311565b811461033757600080fd5b50565b60008135905061034981610323565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126103745761037361034f565b5b8235905067ffffffffffffffff81111561039157610390610354565b5b6020830191508360018202830111156103ad576103ac610359565b5b9250929050565b6000806000806000608086880312156103d0576103cf610271565b5b60006103de8882890161033a565b95505060206103ef8882890161033a565b94505060406104008882890161029c565b935050606086013567ffffffffffffffff81111561042157610420610276565b5b61042d8882890161035e565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6104718161043c565b82525050565b600060208201905061048c6000830184610468565b92915050565b600080604083850312156104a9576104a8610271565b5b60006104b78582860161029c565b92505060206104c88582860161033a565b9150509250929050565b6000819050919050565b60006104f76104f26104ed846102f1565b6104d2565b6102f1565b9050919050565b6000610509826104dc565b9050919050565b600061051b826104fe565b9050919050565b61052b81610510565b82525050565b60006020820190506105466000830184610522565b92915050565b61055581610311565b82525050565b6105648161027b565b82525050565b600060608201905061057f600083018661054c565b61058c602083018561054c565b610599604083018461055b565b949350505050565b60006060820190506105b6600083018661054c565b6105c3602083018561055b565b6105d0604083018461055b565b94935050505056fea2646970667358221220ffe5b1022325b0b50cd2f0aea5d0b9b60235c0cb25dbae9259d6c3b700b8888e64736f6c63430008120033", "devdoc": { "author": "OnGrid Dev Team*", "kind": "dev", @@ -175,16 +175,16 @@ "storageLayout": { "storage": [ { - "astId": 3354, + "astId": 3023, "contract": "contracts/L1BridgeRouter.sol:L1BridgeRouter", "label": "token", "offset": 0, "slot": "0", - "type": "t_contract(IERC721)1431" + "type": "t_contract(IERC721)1155" } ], "types": { - "t_contract(IERC721)1431": { + "t_contract(IERC721)1155": { "encoding": "inplace", "label": "contract IERC721", "numberOfBytes": "20" diff --git a/contracts/deployments/goerli/L1Token.json b/contracts/deployments/goerli/L1Token.json new file mode 100644 index 0000000..2973e35 --- /dev/null +++ b/contracts/deployments/goerli/L1Token.json @@ -0,0 +1,747 @@ +{ + "address": "0xF24cEe7c2e89bbee3620A926fe3Fa9eDDC395402", + "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": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "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" + }, + { + "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": "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": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "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": "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": "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" + } + ], + "transactionHash": "0x022929088822a6061a0919dc3d3d16f236b10d5efd63fa8c0ae133777552c684", + "receipt": { + "to": null, + "from": "0x8289275310690BD0409cF12087F9D504cA24c4D1", + "contractAddress": "0xF24cEe7c2e89bbee3620A926fe3Fa9eDDC395402", + "transactionIndex": 55, + "gasUsed": "2855329", + "logsBloom": "0x00000000000000008000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000020000000000000000000000000020000000000000000000800000000000000000000010000000000400000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000020000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6747a094d9e4956f045f2471d030946bd140b47a765a8293422b219b0483702d", + "transactionHash": "0x022929088822a6061a0919dc3d3d16f236b10d5efd63fa8c0ae133777552c684", + "logs": [ + { + "transactionIndex": 55, + "blockNumber": 8772383, + "transactionHash": "0x022929088822a6061a0919dc3d3d16f236b10d5efd63fa8c0ae133777552c684", + "address": "0xF24cEe7c2e89bbee3620A926fe3Fa9eDDC395402", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008289275310690bd0409cf12087f9d504ca24c4d1" + ], + "data": "0x", + "logIndex": 75, + "blockHash": "0x6747a094d9e4956f045f2471d030946bd140b47a765a8293422b219b0483702d" + } + ], + "blockNumber": 8772383, + "cumulativeGasUsed": "9618664", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "d50704bd3b61e4d6e2bdbdcda49f3f62", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"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\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"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\"},{\"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\":\"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\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"mint\",\"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\":\"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\":\"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\"}],\"devdoc\":{\"author\":\"OnGrid Dev Team*\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address)\":{\"details\":\"Mints a specific to the given address\",\"params\":{\"to\":\"the receiver\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenByIndex(uint256)\":{\"details\":\"See {IERC721Enumerable-tokenByIndex}.\"},\"tokenOfOwnerByIndex(address,uint256)\":{\"details\":\"See {IERC721Enumerable-tokenOfOwnerByIndex}.\"},\"tokenURI(uint256)\":{\"details\":\"See {IERC721Metadata-tokenURI}.\"},\"totalSupply()\":{\"details\":\"See {IERC721Enumerable-totalSupply}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"L1Token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1Token.sol\":\"L1Token\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\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 or 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 or approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\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, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\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, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\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 and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\",\"keccak256\":\"0x1e854874c68bec05be100dc0092cb5fbbc71253d370ae98ddef248bbfc3fe118\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\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\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (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 See {ERC721-_beforeTokenTransfer}.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, firstTokenId, batchSize);\\n\\n if (batchSize > 1) {\\n // Will only trigger during construction. Batch transferring (minting) is not available afterwards.\\n revert(\\\"ERC721Enumerable: consecutive transfers not supported\\\");\\n }\\n\\n uint256 tokenId = firstTokenId;\\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\",\"keccak256\":\"0xa8796bd16014cefb8c26449413981a49c510f92a98d6828494f5fd046223ced3\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"contracts/L1Token.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title L1Token\\n * @author OnGrid Dev Team\\n **/\\ncontract L1Token is ERC721Enumerable, Ownable {\\n using Strings for uint256;\\n\\n constructor() ERC721(\\\"Grizzly\\\", \\\"GRZL\\\") {}\\n\\n /**\\n * @dev Mints a specific to the given address\\n * @param to the receiver\\n */\\n function mint(address to) public {\\n uint256 mintIndex = totalSupply();\\n _safeMint(to, mintIndex);\\n }\\n}\\n\",\"keccak256\":\"0x18a230aa63dc08d57cd3d605e910c0202e4f8d9b266521b8d9d873b496593c10\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280600781526020017f4772697a7a6c79000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f47525a4c0000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000412565b508060019081620000a1919062000412565b505050620000c4620000b8620000ca60201b60201c565b620000d260201b60201c565b620004f9565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200021a57607f821691505b60208210810362000230576200022f620001d2565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200029a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200025b565b620002a686836200025b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002f3620002ed620002e784620002be565b620002c8565b620002be565b9050919050565b6000819050919050565b6200030f83620002d2565b620003276200031e82620002fa565b84845462000268565b825550505050565b600090565b6200033e6200032f565b6200034b81848462000304565b505050565b5b8181101562000373576200036760008262000334565b60018101905062000351565b5050565b601f821115620003c2576200038c8162000236565b62000397846200024b565b81016020851015620003a7578190505b620003bf620003b6856200024b565b83018262000350565b50505b505050565b600082821c905092915050565b6000620003e760001984600802620003c7565b1980831691505092915050565b6000620004028383620003d4565b9150826002028217905092915050565b6200041d8262000198565b67ffffffffffffffff811115620004395762000438620001a3565b5b62000445825462000201565b6200045282828562000377565b600060209050601f8311600181146200048a576000841562000475578287015190505b620004818582620003f4565b865550620004f1565b601f1984166200049a8662000236565b60005b82811015620004c4578489015182556001820191506020850194506020810190506200049d565b86831015620004e45784890151620004e0601f891682620003d4565b8355505b6001600288020188555050505b505050505050565b61315e80620005096000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80636a627842116100ad578063a22cb46511610071578063a22cb46514610343578063b88d4fde1461035f578063c87b56dd1461037b578063e985e9c5146103ab578063f2fde38b146103db5761012c565b80636a627842146102b157806370a08231146102cd578063715018a6146102fd5780638da5cb5b1461030757806395d89b41146103255761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b600480360381019061014691906120e5565b6103f7565b604051610158919061212d565b60405180910390f35b610169610471565b60405161017691906121d8565b60405180910390f35b61019960048036038101906101949190612230565b610503565b6040516101a6919061229e565b60405180910390f35b6101c960048036038101906101c491906122e5565b610549565b005b6101d3610660565b6040516101e09190612334565b60405180910390f35b61020360048036038101906101fe919061234f565b61066d565b005b61021f600480360381019061021a91906122e5565b6106cd565b60405161022c9190612334565b60405180910390f35b61024f600480360381019061024a919061234f565b610772565b005b61026b60048036038101906102669190612230565b610792565b6040516102789190612334565b60405180910390f35b61029b60048036038101906102969190612230565b610803565b6040516102a8919061229e565b60405180910390f35b6102cb60048036038101906102c691906123a2565b610889565b005b6102e760048036038101906102e291906123a2565b6108a3565b6040516102f49190612334565b60405180910390f35b61030561095a565b005b61030f61096e565b60405161031c919061229e565b60405180910390f35b61032d610998565b60405161033a91906121d8565b60405180910390f35b61035d600480360381019061035891906123fb565b610a2a565b005b61037960048036038101906103749190612570565b610a40565b005b61039560048036038101906103909190612230565b610aa2565b6040516103a291906121d8565b60405180910390f35b6103c560048036038101906103c091906125f3565b610b0a565b6040516103d2919061212d565b60405180910390f35b6103f560048036038101906103f091906123a2565b610b9e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061046a575061046982610c21565b5b9050919050565b60606000805461048090612662565b80601f01602080910402602001604051908101604052809291908181526020018280546104ac90612662565b80156104f95780601f106104ce576101008083540402835291602001916104f9565b820191906000526020600020905b8154815290600101906020018083116104dc57829003601f168201915b5050505050905090565b600061050e82610d03565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061055482610803565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bb90612705565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105e3610d4e565b73ffffffffffffffffffffffffffffffffffffffff16148061061257506106118161060c610d4e565b610b0a565b5b610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064890612797565b60405180910390fd5b61065b8383610d56565b505050565b6000600880549050905090565b61067e610678610d4e565b82610e0f565b6106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612829565b60405180910390fd5b6106c8838383610ea4565b505050565b60006106d8836108a3565b8210610719576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610710906128bb565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61078d83838360405180602001604052806000815250610a40565b505050565b600061079c610660565b82106107dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d49061294d565b60405180910390fd5b600882815481106107f1576107f061296d565b5b90600052602060002001549050919050565b60008061080f8361119d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610877906129e8565b60405180910390fd5b80915050919050565b6000610893610660565b905061089f82826111da565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090a90612a7a565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109626111f8565b61096c6000611276565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546109a790612662565b80601f01602080910402602001604051908101604052809291908181526020018280546109d390612662565b8015610a205780601f106109f557610100808354040283529160200191610a20565b820191906000526020600020905b815481529060010190602001808311610a0357829003601f168201915b5050505050905090565b610a3c610a35610d4e565b838361133c565b5050565b610a51610a4b610d4e565b83610e0f565b610a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8790612829565b60405180910390fd5b610a9c848484846114a8565b50505050565b6060610aad82610d03565b6000610ab7611504565b90506000815111610ad75760405180602001604052806000815250610b02565b80610ae18461151b565b604051602001610af2929190612ad6565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610ba66111f8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c90612b6c565b60405180910390fd5b610c1e81611276565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610cec57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610cfc5750610cfb826115e9565b5b9050919050565b610d0c81611653565b610d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d42906129e8565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610dc983610803565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610e1b83610803565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e5d5750610e5c8185610b0a565b5b80610e9b57508373ffffffffffffffffffffffffffffffffffffffff16610e8384610503565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610ec482610803565b73ffffffffffffffffffffffffffffffffffffffff1614610f1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1190612bfe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090612c90565b60405180910390fd5b610f968383836001611694565b8273ffffffffffffffffffffffffffffffffffffffff16610fb682610803565b73ffffffffffffffffffffffffffffffffffffffff161461100c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100390612bfe565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461119883838360016117f2565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6111f48282604051806020016040528060008152506117f8565b5050565b611200610d4e565b73ffffffffffffffffffffffffffffffffffffffff1661121e61096e565b73ffffffffffffffffffffffffffffffffffffffff1614611274576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126b90612cfc565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a190612d68565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161149b919061212d565b60405180910390a3505050565b6114b3848484610ea4565b6114bf84848484611853565b6114fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f590612dfa565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b60606000600161152a846119da565b01905060008167ffffffffffffffff81111561154957611548612445565b5b6040519080825280601f01601f19166020018201604052801561157b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156115de578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816115d2576115d1612e1a565b5b04945060008503611589575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166116758361119d565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6116a084848484611b2d565b60018111156116e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116db90612ebb565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361172b5761172681611b33565b61176a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611769576117688582611b7c565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036117ac576117a781611ce9565b6117eb565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146117ea576117e98482611dba565b5b5b5050505050565b50505050565b6118028383611e39565b61180f6000848484611853565b61184e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184590612dfa565b60405180910390fd5b505050565b60006118748473ffffffffffffffffffffffffffffffffffffffff16612056565b156119cd578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261189d610d4e565b8786866040518563ffffffff1660e01b81526004016118bf9493929190612f30565b6020604051808303816000875af19250505080156118fb57506040513d601f19601f820116820180604052508101906118f89190612f91565b60015b61197d573d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b506000815103611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c90612dfa565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506119d2565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611a38577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611a2e57611a2d612e1a565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611a75576d04ee2d6d415b85acef81000000008381611a6b57611a6a612e1a565b5b0492506020810190505b662386f26fc100008310611aa457662386f26fc100008381611a9a57611a99612e1a565b5b0492506010810190505b6305f5e1008310611acd576305f5e1008381611ac357611ac2612e1a565b5b0492506008810190505b6127108310611af2576127108381611ae857611ae7612e1a565b5b0492506004810190505b60648310611b155760648381611b0b57611b0a612e1a565b5b0492506002810190505b600a8310611b24576001810190505b80915050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611b89846108a3565b611b939190612fed565b9050600060076000848152602001908152602001600020549050818114611c78576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050611cfd9190612fed565b9050600060096000848152602001908152602001600020549050600060088381548110611d2d57611d2c61296d565b5b906000526020600020015490508060088381548110611d4f57611d4e61296d565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480611d9e57611d9d613021565b5b6001900381819060005260206000200160009055905550505050565b6000611dc5836108a3565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9f9061309c565b60405180910390fd5b611eb181611653565b15611ef1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee890613108565b60405180910390fd5b611eff600083836001611694565b611f0881611653565b15611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f90613108565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46120526000838360016117f2565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6120c28161208d565b81146120cd57600080fd5b50565b6000813590506120df816120b9565b92915050565b6000602082840312156120fb576120fa612083565b5b6000612109848285016120d0565b91505092915050565b60008115159050919050565b61212781612112565b82525050565b6000602082019050612142600083018461211e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612182578082015181840152602081019050612167565b60008484015250505050565b6000601f19601f8301169050919050565b60006121aa82612148565b6121b48185612153565b93506121c4818560208601612164565b6121cd8161218e565b840191505092915050565b600060208201905081810360008301526121f2818461219f565b905092915050565b6000819050919050565b61220d816121fa565b811461221857600080fd5b50565b60008135905061222a81612204565b92915050565b60006020828403121561224657612245612083565b5b60006122548482850161221b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006122888261225d565b9050919050565b6122988161227d565b82525050565b60006020820190506122b3600083018461228f565b92915050565b6122c28161227d565b81146122cd57600080fd5b50565b6000813590506122df816122b9565b92915050565b600080604083850312156122fc576122fb612083565b5b600061230a858286016122d0565b925050602061231b8582860161221b565b9150509250929050565b61232e816121fa565b82525050565b60006020820190506123496000830184612325565b92915050565b60008060006060848603121561236857612367612083565b5b6000612376868287016122d0565b9350506020612387868287016122d0565b92505060406123988682870161221b565b9150509250925092565b6000602082840312156123b8576123b7612083565b5b60006123c6848285016122d0565b91505092915050565b6123d881612112565b81146123e357600080fd5b50565b6000813590506123f5816123cf565b92915050565b6000806040838503121561241257612411612083565b5b6000612420858286016122d0565b9250506020612431858286016123e6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61247d8261218e565b810181811067ffffffffffffffff8211171561249c5761249b612445565b5b80604052505050565b60006124af612079565b90506124bb8282612474565b919050565b600067ffffffffffffffff8211156124db576124da612445565b5b6124e48261218e565b9050602081019050919050565b82818337600083830152505050565b600061251361250e846124c0565b6124a5565b90508281526020810184848401111561252f5761252e612440565b5b61253a8482856124f1565b509392505050565b600082601f8301126125575761255661243b565b5b8135612567848260208601612500565b91505092915050565b6000806000806080858703121561258a57612589612083565b5b6000612598878288016122d0565b94505060206125a9878288016122d0565b93505060406125ba8782880161221b565b925050606085013567ffffffffffffffff8111156125db576125da612088565b5b6125e787828801612542565b91505092959194509250565b6000806040838503121561260a57612609612083565b5b6000612618858286016122d0565b9250506020612629858286016122d0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061267a57607f821691505b60208210810361268d5761268c612633565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006126ef602183612153565b91506126fa82612693565b604082019050919050565b6000602082019050818103600083015261271e816126e2565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612781603d83612153565b915061278c82612725565b604082019050919050565b600060208201905081810360008301526127b081612774565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612813602d83612153565b915061281e826127b7565b604082019050919050565b6000602082019050818103600083015261284281612806565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006128a5602b83612153565b91506128b082612849565b604082019050919050565b600060208201905081810360008301526128d481612898565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612937602c83612153565b9150612942826128db565b604082019050919050565b600060208201905081810360008301526129668161292a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006129d2601883612153565b91506129dd8261299c565b602082019050919050565b60006020820190508181036000830152612a01816129c5565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612a64602983612153565b9150612a6f82612a08565b604082019050919050565b60006020820190508181036000830152612a9381612a57565b9050919050565b600081905092915050565b6000612ab082612148565b612aba8185612a9a565b9350612aca818560208601612164565b80840191505092915050565b6000612ae28285612aa5565b9150612aee8284612aa5565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612b56602683612153565b9150612b6182612afa565b604082019050919050565b60006020820190508181036000830152612b8581612b49565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612be8602583612153565b9150612bf382612b8c565b604082019050919050565b60006020820190508181036000830152612c1781612bdb565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612c7a602483612153565b9150612c8582612c1e565b604082019050919050565b60006020820190508181036000830152612ca981612c6d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612ce6602083612153565b9150612cf182612cb0565b602082019050919050565b60006020820190508181036000830152612d1581612cd9565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612d52601983612153565b9150612d5d82612d1c565b602082019050919050565b60006020820190508181036000830152612d8181612d45565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000612de4603283612153565b9150612def82612d88565b604082019050919050565b60006020820190508181036000830152612e1381612dd7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000612ea5603583612153565b9150612eb082612e49565b604082019050919050565b60006020820190508181036000830152612ed481612e98565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612f0282612edb565b612f0c8185612ee6565b9350612f1c818560208601612164565b612f258161218e565b840191505092915050565b6000608082019050612f45600083018761228f565b612f52602083018661228f565b612f5f6040830185612325565b8181036060830152612f718184612ef7565b905095945050505050565b600081519050612f8b816120b9565b92915050565b600060208284031215612fa757612fa6612083565b5b6000612fb584828501612f7c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ff8826121fa565b9150613003836121fa565b925082820390508181111561301b5761301a612fbe565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613086602083612153565b915061309182613050565b602082019050919050565b600060208201905081810360008301526130b581613079565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006130f2601c83612153565b91506130fd826130bc565b602082019050919050565b60006020820190508181036000830152613121816130e5565b905091905056fea2646970667358221220ae16b6aa1c902fbdfe69fe3c3eb8b5b7a145d1d7768fd69c496e8e63d725e44064736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80636a627842116100ad578063a22cb46511610071578063a22cb46514610343578063b88d4fde1461035f578063c87b56dd1461037b578063e985e9c5146103ab578063f2fde38b146103db5761012c565b80636a627842146102b157806370a08231146102cd578063715018a6146102fd5780638da5cb5b1461030757806395d89b41146103255761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b600480360381019061014691906120e5565b6103f7565b604051610158919061212d565b60405180910390f35b610169610471565b60405161017691906121d8565b60405180910390f35b61019960048036038101906101949190612230565b610503565b6040516101a6919061229e565b60405180910390f35b6101c960048036038101906101c491906122e5565b610549565b005b6101d3610660565b6040516101e09190612334565b60405180910390f35b61020360048036038101906101fe919061234f565b61066d565b005b61021f600480360381019061021a91906122e5565b6106cd565b60405161022c9190612334565b60405180910390f35b61024f600480360381019061024a919061234f565b610772565b005b61026b60048036038101906102669190612230565b610792565b6040516102789190612334565b60405180910390f35b61029b60048036038101906102969190612230565b610803565b6040516102a8919061229e565b60405180910390f35b6102cb60048036038101906102c691906123a2565b610889565b005b6102e760048036038101906102e291906123a2565b6108a3565b6040516102f49190612334565b60405180910390f35b61030561095a565b005b61030f61096e565b60405161031c919061229e565b60405180910390f35b61032d610998565b60405161033a91906121d8565b60405180910390f35b61035d600480360381019061035891906123fb565b610a2a565b005b61037960048036038101906103749190612570565b610a40565b005b61039560048036038101906103909190612230565b610aa2565b6040516103a291906121d8565b60405180910390f35b6103c560048036038101906103c091906125f3565b610b0a565b6040516103d2919061212d565b60405180910390f35b6103f560048036038101906103f091906123a2565b610b9e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061046a575061046982610c21565b5b9050919050565b60606000805461048090612662565b80601f01602080910402602001604051908101604052809291908181526020018280546104ac90612662565b80156104f95780601f106104ce576101008083540402835291602001916104f9565b820191906000526020600020905b8154815290600101906020018083116104dc57829003601f168201915b5050505050905090565b600061050e82610d03565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061055482610803565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bb90612705565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105e3610d4e565b73ffffffffffffffffffffffffffffffffffffffff16148061061257506106118161060c610d4e565b610b0a565b5b610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064890612797565b60405180910390fd5b61065b8383610d56565b505050565b6000600880549050905090565b61067e610678610d4e565b82610e0f565b6106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612829565b60405180910390fd5b6106c8838383610ea4565b505050565b60006106d8836108a3565b8210610719576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610710906128bb565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61078d83838360405180602001604052806000815250610a40565b505050565b600061079c610660565b82106107dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d49061294d565b60405180910390fd5b600882815481106107f1576107f061296d565b5b90600052602060002001549050919050565b60008061080f8361119d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610877906129e8565b60405180910390fd5b80915050919050565b6000610893610660565b905061089f82826111da565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090a90612a7a565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109626111f8565b61096c6000611276565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546109a790612662565b80601f01602080910402602001604051908101604052809291908181526020018280546109d390612662565b8015610a205780601f106109f557610100808354040283529160200191610a20565b820191906000526020600020905b815481529060010190602001808311610a0357829003601f168201915b5050505050905090565b610a3c610a35610d4e565b838361133c565b5050565b610a51610a4b610d4e565b83610e0f565b610a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8790612829565b60405180910390fd5b610a9c848484846114a8565b50505050565b6060610aad82610d03565b6000610ab7611504565b90506000815111610ad75760405180602001604052806000815250610b02565b80610ae18461151b565b604051602001610af2929190612ad6565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610ba66111f8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c90612b6c565b60405180910390fd5b610c1e81611276565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610cec57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610cfc5750610cfb826115e9565b5b9050919050565b610d0c81611653565b610d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d42906129e8565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610dc983610803565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610e1b83610803565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e5d5750610e5c8185610b0a565b5b80610e9b57508373ffffffffffffffffffffffffffffffffffffffff16610e8384610503565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610ec482610803565b73ffffffffffffffffffffffffffffffffffffffff1614610f1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1190612bfe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090612c90565b60405180910390fd5b610f968383836001611694565b8273ffffffffffffffffffffffffffffffffffffffff16610fb682610803565b73ffffffffffffffffffffffffffffffffffffffff161461100c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100390612bfe565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461119883838360016117f2565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6111f48282604051806020016040528060008152506117f8565b5050565b611200610d4e565b73ffffffffffffffffffffffffffffffffffffffff1661121e61096e565b73ffffffffffffffffffffffffffffffffffffffff1614611274576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126b90612cfc565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a190612d68565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161149b919061212d565b60405180910390a3505050565b6114b3848484610ea4565b6114bf84848484611853565b6114fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f590612dfa565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b60606000600161152a846119da565b01905060008167ffffffffffffffff81111561154957611548612445565b5b6040519080825280601f01601f19166020018201604052801561157b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156115de578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816115d2576115d1612e1a565b5b04945060008503611589575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166116758361119d565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6116a084848484611b2d565b60018111156116e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116db90612ebb565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361172b5761172681611b33565b61176a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611769576117688582611b7c565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036117ac576117a781611ce9565b6117eb565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146117ea576117e98482611dba565b5b5b5050505050565b50505050565b6118028383611e39565b61180f6000848484611853565b61184e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184590612dfa565b60405180910390fd5b505050565b60006118748473ffffffffffffffffffffffffffffffffffffffff16612056565b156119cd578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261189d610d4e565b8786866040518563ffffffff1660e01b81526004016118bf9493929190612f30565b6020604051808303816000875af19250505080156118fb57506040513d601f19601f820116820180604052508101906118f89190612f91565b60015b61197d573d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b506000815103611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c90612dfa565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506119d2565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611a38577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611a2e57611a2d612e1a565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611a75576d04ee2d6d415b85acef81000000008381611a6b57611a6a612e1a565b5b0492506020810190505b662386f26fc100008310611aa457662386f26fc100008381611a9a57611a99612e1a565b5b0492506010810190505b6305f5e1008310611acd576305f5e1008381611ac357611ac2612e1a565b5b0492506008810190505b6127108310611af2576127108381611ae857611ae7612e1a565b5b0492506004810190505b60648310611b155760648381611b0b57611b0a612e1a565b5b0492506002810190505b600a8310611b24576001810190505b80915050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611b89846108a3565b611b939190612fed565b9050600060076000848152602001908152602001600020549050818114611c78576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050611cfd9190612fed565b9050600060096000848152602001908152602001600020549050600060088381548110611d2d57611d2c61296d565b5b906000526020600020015490508060088381548110611d4f57611d4e61296d565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480611d9e57611d9d613021565b5b6001900381819060005260206000200160009055905550505050565b6000611dc5836108a3565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9f9061309c565b60405180910390fd5b611eb181611653565b15611ef1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee890613108565b60405180910390fd5b611eff600083836001611694565b611f0881611653565b15611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f90613108565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46120526000838360016117f2565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6120c28161208d565b81146120cd57600080fd5b50565b6000813590506120df816120b9565b92915050565b6000602082840312156120fb576120fa612083565b5b6000612109848285016120d0565b91505092915050565b60008115159050919050565b61212781612112565b82525050565b6000602082019050612142600083018461211e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612182578082015181840152602081019050612167565b60008484015250505050565b6000601f19601f8301169050919050565b60006121aa82612148565b6121b48185612153565b93506121c4818560208601612164565b6121cd8161218e565b840191505092915050565b600060208201905081810360008301526121f2818461219f565b905092915050565b6000819050919050565b61220d816121fa565b811461221857600080fd5b50565b60008135905061222a81612204565b92915050565b60006020828403121561224657612245612083565b5b60006122548482850161221b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006122888261225d565b9050919050565b6122988161227d565b82525050565b60006020820190506122b3600083018461228f565b92915050565b6122c28161227d565b81146122cd57600080fd5b50565b6000813590506122df816122b9565b92915050565b600080604083850312156122fc576122fb612083565b5b600061230a858286016122d0565b925050602061231b8582860161221b565b9150509250929050565b61232e816121fa565b82525050565b60006020820190506123496000830184612325565b92915050565b60008060006060848603121561236857612367612083565b5b6000612376868287016122d0565b9350506020612387868287016122d0565b92505060406123988682870161221b565b9150509250925092565b6000602082840312156123b8576123b7612083565b5b60006123c6848285016122d0565b91505092915050565b6123d881612112565b81146123e357600080fd5b50565b6000813590506123f5816123cf565b92915050565b6000806040838503121561241257612411612083565b5b6000612420858286016122d0565b9250506020612431858286016123e6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61247d8261218e565b810181811067ffffffffffffffff8211171561249c5761249b612445565b5b80604052505050565b60006124af612079565b90506124bb8282612474565b919050565b600067ffffffffffffffff8211156124db576124da612445565b5b6124e48261218e565b9050602081019050919050565b82818337600083830152505050565b600061251361250e846124c0565b6124a5565b90508281526020810184848401111561252f5761252e612440565b5b61253a8482856124f1565b509392505050565b600082601f8301126125575761255661243b565b5b8135612567848260208601612500565b91505092915050565b6000806000806080858703121561258a57612589612083565b5b6000612598878288016122d0565b94505060206125a9878288016122d0565b93505060406125ba8782880161221b565b925050606085013567ffffffffffffffff8111156125db576125da612088565b5b6125e787828801612542565b91505092959194509250565b6000806040838503121561260a57612609612083565b5b6000612618858286016122d0565b9250506020612629858286016122d0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061267a57607f821691505b60208210810361268d5761268c612633565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006126ef602183612153565b91506126fa82612693565b604082019050919050565b6000602082019050818103600083015261271e816126e2565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612781603d83612153565b915061278c82612725565b604082019050919050565b600060208201905081810360008301526127b081612774565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612813602d83612153565b915061281e826127b7565b604082019050919050565b6000602082019050818103600083015261284281612806565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006128a5602b83612153565b91506128b082612849565b604082019050919050565b600060208201905081810360008301526128d481612898565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612937602c83612153565b9150612942826128db565b604082019050919050565b600060208201905081810360008301526129668161292a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006129d2601883612153565b91506129dd8261299c565b602082019050919050565b60006020820190508181036000830152612a01816129c5565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612a64602983612153565b9150612a6f82612a08565b604082019050919050565b60006020820190508181036000830152612a9381612a57565b9050919050565b600081905092915050565b6000612ab082612148565b612aba8185612a9a565b9350612aca818560208601612164565b80840191505092915050565b6000612ae28285612aa5565b9150612aee8284612aa5565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612b56602683612153565b9150612b6182612afa565b604082019050919050565b60006020820190508181036000830152612b8581612b49565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612be8602583612153565b9150612bf382612b8c565b604082019050919050565b60006020820190508181036000830152612c1781612bdb565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612c7a602483612153565b9150612c8582612c1e565b604082019050919050565b60006020820190508181036000830152612ca981612c6d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612ce6602083612153565b9150612cf182612cb0565b602082019050919050565b60006020820190508181036000830152612d1581612cd9565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612d52601983612153565b9150612d5d82612d1c565b602082019050919050565b60006020820190508181036000830152612d8181612d45565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000612de4603283612153565b9150612def82612d88565b604082019050919050565b60006020820190508181036000830152612e1381612dd7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000612ea5603583612153565b9150612eb082612e49565b604082019050919050565b60006020820190508181036000830152612ed481612e98565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612f0282612edb565b612f0c8185612ee6565b9350612f1c818560208601612164565b612f258161218e565b840191505092915050565b6000608082019050612f45600083018761228f565b612f52602083018661228f565b612f5f6040830185612325565b8181036060830152612f718184612ef7565b905095945050505050565b600081519050612f8b816120b9565b92915050565b600060208284031215612fa757612fa6612083565b5b6000612fb584828501612f7c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ff8826121fa565b9150613003836121fa565b925082820390508181111561301b5761301a612fbe565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613086602083612153565b915061309182613050565b602082019050919050565b600060208201905081810360008301526130b581613079565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006130f2601c83612153565b91506130fd826130bc565b602082019050919050565b60006020820190508181036000830152613121816130e5565b905091905056fea2646970667358221220ae16b6aa1c902fbdfe69fe3c3eb8b5b7a145d1d7768fd69c496e8e63d725e44064736f6c63430008120033", + "devdoc": { + "author": "OnGrid Dev Team*", + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when `owner` enables `approved` to manage the `tokenId` token." + }, + "ApprovalForAll(address,address,bool)": { + "details": "Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `tokenId` token is transferred from `from` to `to`." + } + }, + "kind": "dev", + "methods": { + "approve(address,uint256)": { + "details": "See {IERC721-approve}." + }, + "balanceOf(address)": { + "details": "See {IERC721-balanceOf}." + }, + "getApproved(uint256)": { + "details": "See {IERC721-getApproved}." + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC721-isApprovedForAll}." + }, + "mint(address)": { + "details": "Mints a specific to the given address", + "params": { + "to": "the receiver" + } + }, + "name()": { + "details": "See {IERC721Metadata-name}." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "ownerOf(uint256)": { + "details": "See {IERC721-ownerOf}." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "safeTransferFrom(address,address,uint256)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "setApprovalForAll(address,bool)": { + "details": "See {IERC721-setApprovalForAll}." + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + }, + "symbol()": { + "details": "See {IERC721Metadata-symbol}." + }, + "tokenByIndex(uint256)": { + "details": "See {IERC721Enumerable-tokenByIndex}." + }, + "tokenOfOwnerByIndex(address,uint256)": { + "details": "See {IERC721Enumerable-tokenOfOwnerByIndex}." + }, + "tokenURI(uint256)": { + "details": "See {IERC721Metadata-tokenURI}." + }, + "totalSupply()": { + "details": "See {IERC721Enumerable-totalSupply}." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC721-transferFrom}." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "title": "L1Token", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 138, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_name", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 140, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_symbol", + "offset": 0, + "slot": "1", + "type": "t_string_storage" + }, + { + "astId": 144, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_owners", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 148, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_balances", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 152, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_tokenApprovals", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 158, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_operatorApprovals", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 1188, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_ownedTokens", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" + }, + { + "astId": 1192, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_ownedTokensIndex", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 1195, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_allTokens", + "offset": 0, + "slot": "8", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 1199, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_allTokensIndex", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 7, + "contract": "contracts/L1Token.sol:L1Token", + "label": "_owner", + "offset": 0, + "slot": "10", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/goerli/L2Token.json b/contracts/deployments/goerli/L2Token.json new file mode 100644 index 0000000..0e1b0d2 --- /dev/null +++ b/contracts/deployments/goerli/L2Token.json @@ -0,0 +1,782 @@ +{ + "address": "0x847800B256657B53Af0c4DeB01a6e786b5D3C501", + "abi": [ + { + "inputs": [ + { + "internalType": "contract L2TokenMinter", + "name": "minter", + "type": "address" + } + ], + "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": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "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" + }, + { + "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": "id", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "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": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "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": "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": "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" + } + ], + "transactionHash": "0xe769e9b739ac2c630487d5e7869458e7b9605f1893ff481b6904735be7be5922", + "receipt": { + "to": null, + "from": "0x8289275310690BD0409cF12087F9D504cA24c4D1", + "contractAddress": "0x847800B256657B53Af0c4DeB01a6e786b5D3C501", + "transactionIndex": 97, + "gasUsed": "2984977", + "logsBloom": "0x00000000000000000000000000000000000100000000000100800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000010000000000400000000000000000000000000000000000000010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000020000000000020000000000000000000000000000000000000000080000000000000", + "blockHash": "0x6ee7f85e389d7456288e81b36ed0596176070dea08d7cf5d18c4f9082dbd5838", + "transactionHash": "0xe769e9b739ac2c630487d5e7869458e7b9605f1893ff481b6904735be7be5922", + "logs": [ + { + "transactionIndex": 97, + "blockNumber": 8772386, + "transactionHash": "0xe769e9b739ac2c630487d5e7869458e7b9605f1893ff481b6904735be7be5922", + "address": "0x847800B256657B53Af0c4DeB01a6e786b5D3C501", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008289275310690bd0409cf12087f9d504ca24c4d1" + ], + "data": "0x", + "logIndex": 119, + "blockHash": "0x6ee7f85e389d7456288e81b36ed0596176070dea08d7cf5d18c4f9082dbd5838" + }, + { + "transactionIndex": 97, + "blockNumber": 8772386, + "transactionHash": "0xe769e9b739ac2c630487d5e7869458e7b9605f1893ff481b6904735be7be5922", + "address": "0x847800B256657B53Af0c4DeB01a6e786b5D3C501", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000008289275310690bd0409cf12087f9d504ca24c4d1", + "0x000000000000000000000000179227d0ba50c7260ed1a6ec7951484ab5db6178" + ], + "data": "0x", + "logIndex": 120, + "blockHash": "0x6ee7f85e389d7456288e81b36ed0596176070dea08d7cf5d18c4f9082dbd5838" + } + ], + "blockNumber": 8772386, + "cumulativeGasUsed": "13600076", + "status": 1, + "byzantium": true + }, + "args": [ + "0x179227D0Ba50c7260ed1A6ec7951484Ab5dB6178" + ], + "numDeployments": 1, + "solcInputHash": "d50704bd3b61e4d6e2bdbdcda49f3f62", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract L2TokenMinter\",\"name\":\"minter\",\"type\":\"address\"}],\"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\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"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\"},{\"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\":\"id\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"mint\",\"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\":\"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\":\"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\"}],\"devdoc\":{\"author\":\"OnGrid Dev Team*\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address)\":{\"details\":\"Mints a specific to the given address\",\"params\":{\"to\":\"the receiver\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenByIndex(uint256)\":{\"details\":\"See {IERC721Enumerable-tokenByIndex}.\"},\"tokenOfOwnerByIndex(address,uint256)\":{\"details\":\"See {IERC721Enumerable-tokenOfOwnerByIndex}.\"},\"tokenURI(uint256)\":{\"details\":\"See {IERC721Metadata-tokenURI}.\"},\"totalSupply()\":{\"details\":\"See {IERC721Enumerable-totalSupply}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"L2Token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2Token.sol\":\"L2Token\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\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 or 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 or approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\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, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\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, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\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 and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\",\"keccak256\":\"0x1e854874c68bec05be100dc0092cb5fbbc71253d370ae98ddef248bbfc3fe118\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\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\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (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 See {ERC721-_beforeTokenTransfer}.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, firstTokenId, batchSize);\\n\\n if (batchSize > 1) {\\n // Will only trigger during construction. Batch transferring (minting) is not available afterwards.\\n revert(\\\"ERC721Enumerable: consecutive transfers not supported\\\");\\n }\\n\\n uint256 tokenId = firstTokenId;\\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\",\"keccak256\":\"0xa8796bd16014cefb8c26449413981a49c510f92a98d6828494f5fd046223ced3\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"contracts/L2Token.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"./L2TokenMinter.sol\\\";\\n\\n/**\\n * @title L2Token\\n * @author OnGrid Dev Team\\n **/\\ncontract L2Token is ERC721Enumerable, Ownable {\\n using Strings for uint256;\\n\\n constructor(\\n L2TokenMinter minter\\n ) ERC721(\\\"Grizzly\\\", \\\"GRZL\\\") {\\n transferOwnership(address(minter));\\n L2TokenMinter a = L2TokenMinter(address(minter));\\n a.setOwnedContract(address(this));\\n }\\n\\n /**\\n * @dev Mints a specific to the given address\\n * @param to the receiver\\n */\\n function mint(address to) public onlyOwner {\\n uint256 mintIndex = totalSupply();\\n _safeMint(to, mintIndex);\\n }\\n\\n function burn(uint256 id) public onlyOwner {\\n _burn(id);\\n }\\n}\\n\",\"keccak256\":\"0x33d89642e3205bd235e0009ef775581954a604fa885fdf17ec3b3d5d99603677\",\"license\":\"GPL-3.0\"},\"contracts/L2TokenMinter.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport \\\"./L2Token.sol\\\";\\n\\ncontract L2TokenMinter {\\n address ownedContract;\\n address owner;\\n\\n constructor () {\\n owner = msg.sender;\\n }\\n\\n function setOwnedContract (address owned) public {\\n ownedContract = owned;\\n }\\n\\n function mintL2 (address to) public {\\n L2Token proxied = L2Token(ownedContract);\\n proxied.mint(to);\\n }\\n}\",\"keccak256\":\"0xf36a02e909c365eee15dc53b1dd817c8ccbf1406bc3ebf6510205152d4326321\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162003bee38038062003bee833981810160405281019062000037919062000413565b6040518060400160405280600781526020017f4772697a7a6c79000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f47525a4c000000000000000000000000000000000000000000000000000000008152508160009081620000b49190620006bf565b508060019081620000c69190620006bf565b505050620000e9620000dd6200017660201b60201c565b6200017e60201b60201c565b620000fa816200024460201b60201c565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663a054534c306040518263ffffffff1660e01b81526004016200013a9190620007b7565b600060405180830381600087803b1580156200015557600080fd5b505af11580156200016a573d6000803e3d6000fd5b505050505050620008ef565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000254620002da60201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620002c6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002bd906200085b565b60405180910390fd5b620002d7816200017e60201b60201c565b50565b620002ea6200017660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620003106200036b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000369576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200036090620008cd565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003c7826200039a565b9050919050565b6000620003db82620003ba565b9050919050565b620003ed81620003ce565b8114620003f957600080fd5b50565b6000815190506200040d81620003e2565b92915050565b6000602082840312156200042c576200042b62000395565b5b60006200043c84828501620003fc565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620004c757607f821691505b602082108103620004dd57620004dc6200047f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000508565b62000553868362000508565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005a06200059a62000594846200056b565b62000575565b6200056b565b9050919050565b6000819050919050565b620005bc836200057f565b620005d4620005cb82620005a7565b84845462000515565b825550505050565b600090565b620005eb620005dc565b620005f8818484620005b1565b505050565b5b81811015620006205762000614600082620005e1565b600181019050620005fe565b5050565b601f8211156200066f576200063981620004e3565b6200064484620004f8565b8101602085101562000654578190505b6200066c6200066385620004f8565b830182620005fd565b50505b505050565b600082821c905092915050565b6000620006946000198460080262000674565b1980831691505092915050565b6000620006af838362000681565b9150826002028217905092915050565b620006ca8262000445565b67ffffffffffffffff811115620006e657620006e562000450565b5b620006f28254620004ae565b620006ff82828562000624565b600060209050601f83116001811462000737576000841562000722578287015190505b6200072e8582620006a1565b8655506200079e565b601f1984166200074786620004e3565b60005b8281101562000771578489015182556001820191506020850194506020810190506200074a565b868310156200079157848901516200078d601f89168262000681565b8355505b6001600288020188555050505b505050505050565b620007b181620003ba565b82525050565b6000602082019050620007ce6000830184620007a6565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600062000843602683620007d4565b91506200085082620007e5565b604082019050919050565b60006020820190508181036000830152620008768162000834565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620008b5602083620007d4565b9150620008c2826200087d565b602082019050919050565b60006020820190508181036000830152620008e881620008a6565b9050919050565b6132ef80620008ff6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80636352211e116100b857806395d89b411161007c57806395d89b411461034c578063a22cb4651461036a578063b88d4fde14610386578063c87b56dd146103a2578063e985e9c5146103d2578063f2fde38b1461040257610137565b80636352211e146102a85780636a627842146102d857806370a08231146102f4578063715018a6146103245780638da5cb5b1461032e57610137565b806323b872dd116100ff57806323b872dd146101f45780632f745c591461021057806342842e0e1461024057806342966c681461025c5780634f6ccce71461027857610137565b806301ffc9a71461013c57806306fdde031461016c578063081812fc1461018a578063095ea7b3146101ba57806318160ddd146101d6575b600080fd5b61015660048036038101906101519190612276565b61041e565b60405161016391906122be565b60405180910390f35b610174610498565b6040516101819190612369565b60405180910390f35b6101a4600480360381019061019f91906123c1565b61052a565b6040516101b1919061242f565b60405180910390f35b6101d460048036038101906101cf9190612476565b610570565b005b6101de610687565b6040516101eb91906124c5565b60405180910390f35b61020e600480360381019061020991906124e0565b610694565b005b61022a60048036038101906102259190612476565b6106f4565b60405161023791906124c5565b60405180910390f35b61025a600480360381019061025591906124e0565b610799565b005b610276600480360381019061027191906123c1565b6107b9565b005b610292600480360381019061028d91906123c1565b6107cd565b60405161029f91906124c5565b60405180910390f35b6102c260048036038101906102bd91906123c1565b61083e565b6040516102cf919061242f565b60405180910390f35b6102f260048036038101906102ed9190612533565b6108c4565b005b61030e60048036038101906103099190612533565b6108e6565b60405161031b91906124c5565b60405180910390f35b61032c61099d565b005b6103366109b1565b604051610343919061242f565b60405180910390f35b6103546109db565b6040516103619190612369565b60405180910390f35b610384600480360381019061037f919061258c565b610a6d565b005b6103a0600480360381019061039b9190612701565b610a83565b005b6103bc60048036038101906103b791906123c1565b610ae5565b6040516103c99190612369565b60405180910390f35b6103ec60048036038101906103e79190612784565b610b4d565b6040516103f991906122be565b60405180910390f35b61041c60048036038101906104179190612533565b610be1565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610491575061049082610c64565b5b9050919050565b6060600080546104a7906127f3565b80601f01602080910402602001604051908101604052809291908181526020018280546104d3906127f3565b80156105205780601f106104f557610100808354040283529160200191610520565b820191906000526020600020905b81548152906001019060200180831161050357829003601f168201915b5050505050905090565b600061053582610d46565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061057b8261083e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e290612896565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661060a610d91565b73ffffffffffffffffffffffffffffffffffffffff161480610639575061063881610633610d91565b610b4d565b5b610678576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066f90612928565b60405180910390fd5b6106828383610d99565b505050565b6000600880549050905090565b6106a561069f610d91565b82610e52565b6106e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106db906129ba565b60405180910390fd5b6106ef838383610ee7565b505050565b60006106ff836108e6565b8210610740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073790612a4c565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6107b483838360405180602001604052806000815250610a83565b505050565b6107c16111e0565b6107ca8161125e565b50565b60006107d7610687565b8210610818576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080f90612ade565b60405180910390fd5b6008828154811061082c5761082b612afe565b5b90600052602060002001549050919050565b60008061084a836113ac565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b290612b79565b60405180910390fd5b80915050919050565b6108cc6111e0565b60006108d6610687565b90506108e282826113e9565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094d90612c0b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109a56111e0565b6109af6000611407565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546109ea906127f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610a16906127f3565b8015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b5050505050905090565b610a7f610a78610d91565b83836114cd565b5050565b610a94610a8e610d91565b83610e52565b610ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aca906129ba565b60405180910390fd5b610adf84848484611639565b50505050565b6060610af082610d46565b6000610afa611695565b90506000815111610b1a5760405180602001604052806000815250610b45565b80610b24846116ac565b604051602001610b35929190612c67565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610be96111e0565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4f90612cfd565b60405180910390fd5b610c6181611407565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d2f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d3f5750610d3e8261177a565b5b9050919050565b610d4f816117e4565b610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8590612b79565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610e0c8361083e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610e5e8361083e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610ea05750610e9f8185610b4d565b5b80610ede57508373ffffffffffffffffffffffffffffffffffffffff16610ec68461052a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610f078261083e565b73ffffffffffffffffffffffffffffffffffffffff1614610f5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5490612d8f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc390612e21565b60405180910390fd5b610fd98383836001611825565b8273ffffffffffffffffffffffffffffffffffffffff16610ff98261083e565b73ffffffffffffffffffffffffffffffffffffffff161461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104690612d8f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46111db8383836001611983565b505050565b6111e8610d91565b73ffffffffffffffffffffffffffffffffffffffff166112066109b1565b73ffffffffffffffffffffffffffffffffffffffff161461125c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125390612e8d565b60405180910390fd5b565b60006112698261083e565b9050611279816000846001611825565b6112828261083e565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46113a8816000846001611983565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611403828260405180602001604052806000815250611989565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153290612ef9565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161162c91906122be565b60405180910390a3505050565b611644848484610ee7565b611650848484846119e4565b61168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168690612f8b565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b6060600060016116bb84611b6b565b01905060008167ffffffffffffffff8111156116da576116d96125d6565b5b6040519080825280601f01601f19166020018201604052801561170c5781602001600182028036833780820191505090505b509050600082602001820190505b60011561176f578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161176357611762612fab565b5b0494506000850361171a575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16611806836113ac565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61183184848484611cbe565b6001811115611875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186c9061304c565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036118bc576118b781611cc4565b6118fb565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146118fa576118f98582611d0d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361193d5761193881611e7a565b61197c565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461197b5761197a8482611f4b565b5b5b5050505050565b50505050565b6119938383611fca565b6119a060008484846119e4565b6119df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d690612f8b565b60405180910390fd5b505050565b6000611a058473ffffffffffffffffffffffffffffffffffffffff166121e7565b15611b5e578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a2e610d91565b8786866040518563ffffffff1660e01b8152600401611a5094939291906130c1565b6020604051808303816000875af1925050508015611a8c57506040513d601f19601f82011682018060405250810190611a899190613122565b60015b611b0e573d8060008114611abc576040519150601f19603f3d011682016040523d82523d6000602084013e611ac1565b606091505b506000815103611b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afd90612f8b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611b63565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611bc9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611bbf57611bbe612fab565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611c06576d04ee2d6d415b85acef81000000008381611bfc57611bfb612fab565b5b0492506020810190505b662386f26fc100008310611c3557662386f26fc100008381611c2b57611c2a612fab565b5b0492506010810190505b6305f5e1008310611c5e576305f5e1008381611c5457611c53612fab565b5b0492506008810190505b6127108310611c83576127108381611c7957611c78612fab565b5b0492506004810190505b60648310611ca65760648381611c9c57611c9b612fab565b5b0492506002810190505b600a8310611cb5576001810190505b80915050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611d1a846108e6565b611d24919061317e565b9050600060076000848152602001908152602001600020549050818114611e09576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050611e8e919061317e565b9050600060096000848152602001908152602001600020549050600060088381548110611ebe57611ebd612afe565b5b906000526020600020015490508060088381548110611ee057611edf612afe565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480611f2f57611f2e6131b2565b5b6001900381819060005260206000200160009055905550505050565b6000611f56836108e6565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612039576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120309061322d565b60405180910390fd5b612042816117e4565b15612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207990613299565b60405180910390fd5b612090600083836001611825565b612099816117e4565b156120d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d090613299565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121e3600083836001611983565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6122538161221e565b811461225e57600080fd5b50565b6000813590506122708161224a565b92915050565b60006020828403121561228c5761228b612214565b5b600061229a84828501612261565b91505092915050565b60008115159050919050565b6122b8816122a3565b82525050565b60006020820190506122d360008301846122af565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123135780820151818401526020810190506122f8565b60008484015250505050565b6000601f19601f8301169050919050565b600061233b826122d9565b61234581856122e4565b93506123558185602086016122f5565b61235e8161231f565b840191505092915050565b600060208201905081810360008301526123838184612330565b905092915050565b6000819050919050565b61239e8161238b565b81146123a957600080fd5b50565b6000813590506123bb81612395565b92915050565b6000602082840312156123d7576123d6612214565b5b60006123e5848285016123ac565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612419826123ee565b9050919050565b6124298161240e565b82525050565b60006020820190506124446000830184612420565b92915050565b6124538161240e565b811461245e57600080fd5b50565b6000813590506124708161244a565b92915050565b6000806040838503121561248d5761248c612214565b5b600061249b85828601612461565b92505060206124ac858286016123ac565b9150509250929050565b6124bf8161238b565b82525050565b60006020820190506124da60008301846124b6565b92915050565b6000806000606084860312156124f9576124f8612214565b5b600061250786828701612461565b935050602061251886828701612461565b9250506040612529868287016123ac565b9150509250925092565b60006020828403121561254957612548612214565b5b600061255784828501612461565b91505092915050565b612569816122a3565b811461257457600080fd5b50565b60008135905061258681612560565b92915050565b600080604083850312156125a3576125a2612214565b5b60006125b185828601612461565b92505060206125c285828601612577565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61260e8261231f565b810181811067ffffffffffffffff8211171561262d5761262c6125d6565b5b80604052505050565b600061264061220a565b905061264c8282612605565b919050565b600067ffffffffffffffff82111561266c5761266b6125d6565b5b6126758261231f565b9050602081019050919050565b82818337600083830152505050565b60006126a461269f84612651565b612636565b9050828152602081018484840111156126c0576126bf6125d1565b5b6126cb848285612682565b509392505050565b600082601f8301126126e8576126e76125cc565b5b81356126f8848260208601612691565b91505092915050565b6000806000806080858703121561271b5761271a612214565b5b600061272987828801612461565b945050602061273a87828801612461565b935050604061274b878288016123ac565b925050606085013567ffffffffffffffff81111561276c5761276b612219565b5b612778878288016126d3565b91505092959194509250565b6000806040838503121561279b5761279a612214565b5b60006127a985828601612461565b92505060206127ba85828601612461565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061280b57607f821691505b60208210810361281e5761281d6127c4565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006128806021836122e4565b915061288b82612824565b604082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612912603d836122e4565b915061291d826128b6565b604082019050919050565b6000602082019050818103600083015261294181612905565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b60006129a4602d836122e4565b91506129af82612948565b604082019050919050565b600060208201905081810360008301526129d381612997565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612a36602b836122e4565b9150612a41826129da565b604082019050919050565b60006020820190508181036000830152612a6581612a29565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612ac8602c836122e4565b9150612ad382612a6c565b604082019050919050565b60006020820190508181036000830152612af781612abb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612b636018836122e4565b9150612b6e82612b2d565b602082019050919050565b60006020820190508181036000830152612b9281612b56565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612bf56029836122e4565b9150612c0082612b99565b604082019050919050565b60006020820190508181036000830152612c2481612be8565b9050919050565b600081905092915050565b6000612c41826122d9565b612c4b8185612c2b565b9350612c5b8185602086016122f5565b80840191505092915050565b6000612c738285612c36565b9150612c7f8284612c36565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612ce76026836122e4565b9150612cf282612c8b565b604082019050919050565b60006020820190508181036000830152612d1681612cda565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612d796025836122e4565b9150612d8482612d1d565b604082019050919050565b60006020820190508181036000830152612da881612d6c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612e0b6024836122e4565b9150612e1682612daf565b604082019050919050565b60006020820190508181036000830152612e3a81612dfe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e776020836122e4565b9150612e8282612e41565b602082019050919050565b60006020820190508181036000830152612ea681612e6a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612ee36019836122e4565b9150612eee82612ead565b602082019050919050565b60006020820190508181036000830152612f1281612ed6565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000612f756032836122e4565b9150612f8082612f19565b604082019050919050565b60006020820190508181036000830152612fa481612f68565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006130366035836122e4565b915061304182612fda565b604082019050919050565b6000602082019050818103600083015261306581613029565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006130938261306c565b61309d8185613077565b93506130ad8185602086016122f5565b6130b68161231f565b840191505092915050565b60006080820190506130d66000830187612420565b6130e36020830186612420565b6130f060408301856124b6565b81810360608301526131028184613088565b905095945050505050565b60008151905061311c8161224a565b92915050565b60006020828403121561313857613137612214565b5b60006131468482850161310d565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006131898261238b565b91506131948361238b565b92508282039050818111156131ac576131ab61314f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006132176020836122e4565b9150613222826131e1565b602082019050919050565b600060208201905081810360008301526132468161320a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613283601c836122e4565b915061328e8261324d565b602082019050919050565b600060208201905081810360008301526132b281613276565b905091905056fea2646970667358221220474b57a7c6912c3f86cec158dc8ab2d43ae956d9b29a0345c51412d7e6ebb2cd64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101375760003560e01c80636352211e116100b857806395d89b411161007c57806395d89b411461034c578063a22cb4651461036a578063b88d4fde14610386578063c87b56dd146103a2578063e985e9c5146103d2578063f2fde38b1461040257610137565b80636352211e146102a85780636a627842146102d857806370a08231146102f4578063715018a6146103245780638da5cb5b1461032e57610137565b806323b872dd116100ff57806323b872dd146101f45780632f745c591461021057806342842e0e1461024057806342966c681461025c5780634f6ccce71461027857610137565b806301ffc9a71461013c57806306fdde031461016c578063081812fc1461018a578063095ea7b3146101ba57806318160ddd146101d6575b600080fd5b61015660048036038101906101519190612276565b61041e565b60405161016391906122be565b60405180910390f35b610174610498565b6040516101819190612369565b60405180910390f35b6101a4600480360381019061019f91906123c1565b61052a565b6040516101b1919061242f565b60405180910390f35b6101d460048036038101906101cf9190612476565b610570565b005b6101de610687565b6040516101eb91906124c5565b60405180910390f35b61020e600480360381019061020991906124e0565b610694565b005b61022a60048036038101906102259190612476565b6106f4565b60405161023791906124c5565b60405180910390f35b61025a600480360381019061025591906124e0565b610799565b005b610276600480360381019061027191906123c1565b6107b9565b005b610292600480360381019061028d91906123c1565b6107cd565b60405161029f91906124c5565b60405180910390f35b6102c260048036038101906102bd91906123c1565b61083e565b6040516102cf919061242f565b60405180910390f35b6102f260048036038101906102ed9190612533565b6108c4565b005b61030e60048036038101906103099190612533565b6108e6565b60405161031b91906124c5565b60405180910390f35b61032c61099d565b005b6103366109b1565b604051610343919061242f565b60405180910390f35b6103546109db565b6040516103619190612369565b60405180910390f35b610384600480360381019061037f919061258c565b610a6d565b005b6103a0600480360381019061039b9190612701565b610a83565b005b6103bc60048036038101906103b791906123c1565b610ae5565b6040516103c99190612369565b60405180910390f35b6103ec60048036038101906103e79190612784565b610b4d565b6040516103f991906122be565b60405180910390f35b61041c60048036038101906104179190612533565b610be1565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610491575061049082610c64565b5b9050919050565b6060600080546104a7906127f3565b80601f01602080910402602001604051908101604052809291908181526020018280546104d3906127f3565b80156105205780601f106104f557610100808354040283529160200191610520565b820191906000526020600020905b81548152906001019060200180831161050357829003601f168201915b5050505050905090565b600061053582610d46565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061057b8261083e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e290612896565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661060a610d91565b73ffffffffffffffffffffffffffffffffffffffff161480610639575061063881610633610d91565b610b4d565b5b610678576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066f90612928565b60405180910390fd5b6106828383610d99565b505050565b6000600880549050905090565b6106a561069f610d91565b82610e52565b6106e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106db906129ba565b60405180910390fd5b6106ef838383610ee7565b505050565b60006106ff836108e6565b8210610740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073790612a4c565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6107b483838360405180602001604052806000815250610a83565b505050565b6107c16111e0565b6107ca8161125e565b50565b60006107d7610687565b8210610818576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080f90612ade565b60405180910390fd5b6008828154811061082c5761082b612afe565b5b90600052602060002001549050919050565b60008061084a836113ac565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b290612b79565b60405180910390fd5b80915050919050565b6108cc6111e0565b60006108d6610687565b90506108e282826113e9565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094d90612c0b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109a56111e0565b6109af6000611407565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546109ea906127f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610a16906127f3565b8015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b5050505050905090565b610a7f610a78610d91565b83836114cd565b5050565b610a94610a8e610d91565b83610e52565b610ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aca906129ba565b60405180910390fd5b610adf84848484611639565b50505050565b6060610af082610d46565b6000610afa611695565b90506000815111610b1a5760405180602001604052806000815250610b45565b80610b24846116ac565b604051602001610b35929190612c67565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610be96111e0565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4f90612cfd565b60405180910390fd5b610c6181611407565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d2f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d3f5750610d3e8261177a565b5b9050919050565b610d4f816117e4565b610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8590612b79565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610e0c8361083e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610e5e8361083e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610ea05750610e9f8185610b4d565b5b80610ede57508373ffffffffffffffffffffffffffffffffffffffff16610ec68461052a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610f078261083e565b73ffffffffffffffffffffffffffffffffffffffff1614610f5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5490612d8f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc390612e21565b60405180910390fd5b610fd98383836001611825565b8273ffffffffffffffffffffffffffffffffffffffff16610ff98261083e565b73ffffffffffffffffffffffffffffffffffffffff161461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104690612d8f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46111db8383836001611983565b505050565b6111e8610d91565b73ffffffffffffffffffffffffffffffffffffffff166112066109b1565b73ffffffffffffffffffffffffffffffffffffffff161461125c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125390612e8d565b60405180910390fd5b565b60006112698261083e565b9050611279816000846001611825565b6112828261083e565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46113a8816000846001611983565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611403828260405180602001604052806000815250611989565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153290612ef9565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161162c91906122be565b60405180910390a3505050565b611644848484610ee7565b611650848484846119e4565b61168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168690612f8b565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b6060600060016116bb84611b6b565b01905060008167ffffffffffffffff8111156116da576116d96125d6565b5b6040519080825280601f01601f19166020018201604052801561170c5781602001600182028036833780820191505090505b509050600082602001820190505b60011561176f578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161176357611762612fab565b5b0494506000850361171a575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16611806836113ac565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61183184848484611cbe565b6001811115611875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186c9061304c565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036118bc576118b781611cc4565b6118fb565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146118fa576118f98582611d0d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361193d5761193881611e7a565b61197c565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461197b5761197a8482611f4b565b5b5b5050505050565b50505050565b6119938383611fca565b6119a060008484846119e4565b6119df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d690612f8b565b60405180910390fd5b505050565b6000611a058473ffffffffffffffffffffffffffffffffffffffff166121e7565b15611b5e578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a2e610d91565b8786866040518563ffffffff1660e01b8152600401611a5094939291906130c1565b6020604051808303816000875af1925050508015611a8c57506040513d601f19601f82011682018060405250810190611a899190613122565b60015b611b0e573d8060008114611abc576040519150601f19603f3d011682016040523d82523d6000602084013e611ac1565b606091505b506000815103611b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afd90612f8b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611b63565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611bc9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611bbf57611bbe612fab565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611c06576d04ee2d6d415b85acef81000000008381611bfc57611bfb612fab565b5b0492506020810190505b662386f26fc100008310611c3557662386f26fc100008381611c2b57611c2a612fab565b5b0492506010810190505b6305f5e1008310611c5e576305f5e1008381611c5457611c53612fab565b5b0492506008810190505b6127108310611c83576127108381611c7957611c78612fab565b5b0492506004810190505b60648310611ca65760648381611c9c57611c9b612fab565b5b0492506002810190505b600a8310611cb5576001810190505b80915050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611d1a846108e6565b611d24919061317e565b9050600060076000848152602001908152602001600020549050818114611e09576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050611e8e919061317e565b9050600060096000848152602001908152602001600020549050600060088381548110611ebe57611ebd612afe565b5b906000526020600020015490508060088381548110611ee057611edf612afe565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480611f2f57611f2e6131b2565b5b6001900381819060005260206000200160009055905550505050565b6000611f56836108e6565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612039576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120309061322d565b60405180910390fd5b612042816117e4565b15612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207990613299565b60405180910390fd5b612090600083836001611825565b612099816117e4565b156120d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d090613299565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121e3600083836001611983565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6122538161221e565b811461225e57600080fd5b50565b6000813590506122708161224a565b92915050565b60006020828403121561228c5761228b612214565b5b600061229a84828501612261565b91505092915050565b60008115159050919050565b6122b8816122a3565b82525050565b60006020820190506122d360008301846122af565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123135780820151818401526020810190506122f8565b60008484015250505050565b6000601f19601f8301169050919050565b600061233b826122d9565b61234581856122e4565b93506123558185602086016122f5565b61235e8161231f565b840191505092915050565b600060208201905081810360008301526123838184612330565b905092915050565b6000819050919050565b61239e8161238b565b81146123a957600080fd5b50565b6000813590506123bb81612395565b92915050565b6000602082840312156123d7576123d6612214565b5b60006123e5848285016123ac565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612419826123ee565b9050919050565b6124298161240e565b82525050565b60006020820190506124446000830184612420565b92915050565b6124538161240e565b811461245e57600080fd5b50565b6000813590506124708161244a565b92915050565b6000806040838503121561248d5761248c612214565b5b600061249b85828601612461565b92505060206124ac858286016123ac565b9150509250929050565b6124bf8161238b565b82525050565b60006020820190506124da60008301846124b6565b92915050565b6000806000606084860312156124f9576124f8612214565b5b600061250786828701612461565b935050602061251886828701612461565b9250506040612529868287016123ac565b9150509250925092565b60006020828403121561254957612548612214565b5b600061255784828501612461565b91505092915050565b612569816122a3565b811461257457600080fd5b50565b60008135905061258681612560565b92915050565b600080604083850312156125a3576125a2612214565b5b60006125b185828601612461565b92505060206125c285828601612577565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61260e8261231f565b810181811067ffffffffffffffff8211171561262d5761262c6125d6565b5b80604052505050565b600061264061220a565b905061264c8282612605565b919050565b600067ffffffffffffffff82111561266c5761266b6125d6565b5b6126758261231f565b9050602081019050919050565b82818337600083830152505050565b60006126a461269f84612651565b612636565b9050828152602081018484840111156126c0576126bf6125d1565b5b6126cb848285612682565b509392505050565b600082601f8301126126e8576126e76125cc565b5b81356126f8848260208601612691565b91505092915050565b6000806000806080858703121561271b5761271a612214565b5b600061272987828801612461565b945050602061273a87828801612461565b935050604061274b878288016123ac565b925050606085013567ffffffffffffffff81111561276c5761276b612219565b5b612778878288016126d3565b91505092959194509250565b6000806040838503121561279b5761279a612214565b5b60006127a985828601612461565b92505060206127ba85828601612461565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061280b57607f821691505b60208210810361281e5761281d6127c4565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006128806021836122e4565b915061288b82612824565b604082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612912603d836122e4565b915061291d826128b6565b604082019050919050565b6000602082019050818103600083015261294181612905565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b60006129a4602d836122e4565b91506129af82612948565b604082019050919050565b600060208201905081810360008301526129d381612997565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612a36602b836122e4565b9150612a41826129da565b604082019050919050565b60006020820190508181036000830152612a6581612a29565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612ac8602c836122e4565b9150612ad382612a6c565b604082019050919050565b60006020820190508181036000830152612af781612abb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612b636018836122e4565b9150612b6e82612b2d565b602082019050919050565b60006020820190508181036000830152612b9281612b56565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612bf56029836122e4565b9150612c0082612b99565b604082019050919050565b60006020820190508181036000830152612c2481612be8565b9050919050565b600081905092915050565b6000612c41826122d9565b612c4b8185612c2b565b9350612c5b8185602086016122f5565b80840191505092915050565b6000612c738285612c36565b9150612c7f8284612c36565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612ce76026836122e4565b9150612cf282612c8b565b604082019050919050565b60006020820190508181036000830152612d1681612cda565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612d796025836122e4565b9150612d8482612d1d565b604082019050919050565b60006020820190508181036000830152612da881612d6c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612e0b6024836122e4565b9150612e1682612daf565b604082019050919050565b60006020820190508181036000830152612e3a81612dfe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e776020836122e4565b9150612e8282612e41565b602082019050919050565b60006020820190508181036000830152612ea681612e6a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612ee36019836122e4565b9150612eee82612ead565b602082019050919050565b60006020820190508181036000830152612f1281612ed6565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000612f756032836122e4565b9150612f8082612f19565b604082019050919050565b60006020820190508181036000830152612fa481612f68565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006130366035836122e4565b915061304182612fda565b604082019050919050565b6000602082019050818103600083015261306581613029565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006130938261306c565b61309d8185613077565b93506130ad8185602086016122f5565b6130b68161231f565b840191505092915050565b60006080820190506130d66000830187612420565b6130e36020830186612420565b6130f060408301856124b6565b81810360608301526131028184613088565b905095945050505050565b60008151905061311c8161224a565b92915050565b60006020828403121561313857613137612214565b5b60006131468482850161310d565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006131898261238b565b91506131948361238b565b92508282039050818111156131ac576131ab61314f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006132176020836122e4565b9150613222826131e1565b602082019050919050565b600060208201905081810360008301526132468161320a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613283601c836122e4565b915061328e8261324d565b602082019050919050565b600060208201905081810360008301526132b281613276565b905091905056fea2646970667358221220474b57a7c6912c3f86cec158dc8ab2d43ae956d9b29a0345c51412d7e6ebb2cd64736f6c63430008120033", + "devdoc": { + "author": "OnGrid Dev Team*", + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when `owner` enables `approved` to manage the `tokenId` token." + }, + "ApprovalForAll(address,address,bool)": { + "details": "Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `tokenId` token is transferred from `from` to `to`." + } + }, + "kind": "dev", + "methods": { + "approve(address,uint256)": { + "details": "See {IERC721-approve}." + }, + "balanceOf(address)": { + "details": "See {IERC721-balanceOf}." + }, + "getApproved(uint256)": { + "details": "See {IERC721-getApproved}." + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC721-isApprovedForAll}." + }, + "mint(address)": { + "details": "Mints a specific to the given address", + "params": { + "to": "the receiver" + } + }, + "name()": { + "details": "See {IERC721Metadata-name}." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "ownerOf(uint256)": { + "details": "See {IERC721-ownerOf}." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "safeTransferFrom(address,address,uint256)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "setApprovalForAll(address,bool)": { + "details": "See {IERC721-setApprovalForAll}." + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + }, + "symbol()": { + "details": "See {IERC721Metadata-symbol}." + }, + "tokenByIndex(uint256)": { + "details": "See {IERC721Enumerable-tokenByIndex}." + }, + "tokenOfOwnerByIndex(address,uint256)": { + "details": "See {IERC721Enumerable-tokenOfOwnerByIndex}." + }, + "tokenURI(uint256)": { + "details": "See {IERC721Metadata-tokenURI}." + }, + "totalSupply()": { + "details": "See {IERC721Enumerable-totalSupply}." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC721-transferFrom}." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "title": "L2Token", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 138, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_name", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 140, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_symbol", + "offset": 0, + "slot": "1", + "type": "t_string_storage" + }, + { + "astId": 144, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_owners", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 148, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_balances", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 152, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_tokenApprovals", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 158, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_operatorApprovals", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 1188, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_ownedTokens", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" + }, + { + "astId": 1192, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_ownedTokensIndex", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 1195, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_allTokens", + "offset": 0, + "slot": "8", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 1199, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_allTokensIndex", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 7, + "contract": "contracts/L2Token.sol:L2Token", + "label": "_owner", + "offset": 0, + "slot": "10", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/goerli/L2TokenMinter.json b/contracts/deployments/goerli/L2TokenMinter.json new file mode 100644 index 0000000..9aea74b --- /dev/null +++ b/contracts/deployments/goerli/L2TokenMinter.json @@ -0,0 +1,95 @@ +{ + "address": "0x179227D0Ba50c7260ed1A6ec7951484Ab5dB6178", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mintL2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owned", + "type": "address" + } + ], + "name": "setOwnedContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x3a0ab906f5b7440ace3564fc01c021bbc1899a66aa9e4697a6ef32c805853305", + "receipt": { + "to": null, + "from": "0x8289275310690BD0409cF12087F9D504cA24c4D1", + "contractAddress": "0x179227D0Ba50c7260ed1A6ec7951484Ab5dB6178", + "transactionIndex": 76, + "gasUsed": "199739", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x42b0a815c24e822efcc37a2d1f020107d7ed7a0d126db30b8124fa3269a29714", + "transactionHash": "0x3a0ab906f5b7440ace3564fc01c021bbc1899a66aa9e4697a6ef32c805853305", + "logs": [], + "blockNumber": 8772385, + "cumulativeGasUsed": "5960740", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "d50704bd3b61e4d6e2bdbdcda49f3f62", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"mintL2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owned\",\"type\":\"address\"}],\"name\":\"setOwnedContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2TokenMinter.sol\":\"L2TokenMinter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\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 or 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 or approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\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, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\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, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\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 and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\",\"keccak256\":\"0x1e854874c68bec05be100dc0092cb5fbbc71253d370ae98ddef248bbfc3fe118\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\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\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (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 See {ERC721-_beforeTokenTransfer}.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 firstTokenId,\\n uint256 batchSize\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, firstTokenId, batchSize);\\n\\n if (batchSize > 1) {\\n // Will only trigger during construction. Batch transferring (minting) is not available afterwards.\\n revert(\\\"ERC721Enumerable: consecutive transfers not supported\\\");\\n }\\n\\n uint256 tokenId = firstTokenId;\\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\",\"keccak256\":\"0xa8796bd16014cefb8c26449413981a49c510f92a98d6828494f5fd046223ced3\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"contracts/L2Token.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport \\\"./L2TokenMinter.sol\\\";\\n\\n/**\\n * @title L2Token\\n * @author OnGrid Dev Team\\n **/\\ncontract L2Token is ERC721Enumerable, Ownable {\\n using Strings for uint256;\\n\\n constructor(\\n L2TokenMinter minter\\n ) ERC721(\\\"Grizzly\\\", \\\"GRZL\\\") {\\n transferOwnership(address(minter));\\n L2TokenMinter a = L2TokenMinter(address(minter));\\n a.setOwnedContract(address(this));\\n }\\n\\n /**\\n * @dev Mints a specific to the given address\\n * @param to the receiver\\n */\\n function mint(address to) public onlyOwner {\\n uint256 mintIndex = totalSupply();\\n _safeMint(to, mintIndex);\\n }\\n\\n function burn(uint256 id) public onlyOwner {\\n _burn(id);\\n }\\n}\\n\",\"keccak256\":\"0x33d89642e3205bd235e0009ef775581954a604fa885fdf17ec3b3d5d99603677\",\"license\":\"GPL-3.0\"},\"contracts/L2TokenMinter.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.18;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport \\\"./L2Token.sol\\\";\\n\\ncontract L2TokenMinter {\\n address ownedContract;\\n address owner;\\n\\n constructor () {\\n owner = msg.sender;\\n }\\n\\n function setOwnedContract (address owned) public {\\n ownedContract = owned;\\n }\\n\\n function mintL2 (address to) public {\\n L2Token proxied = L2Token(ownedContract);\\n proxied.mint(to);\\n }\\n}\",\"keccak256\":\"0xf36a02e909c365eee15dc53b1dd817c8ccbf1406bc3ebf6510205152d4326321\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061023b806100616000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a054534c1461003b578063dbc5353c14610057575b600080fd5b610055600480360381019061005091906101ae565b610073565b005b610071600480360381019061006c91906101ae565b6100b6565b005b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16636a627842836040518263ffffffff1660e01b815260040161011591906101ea565b600060405180830381600087803b15801561012f57600080fd5b505af1158015610143573d6000803e3d6000fd5b505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061017b82610150565b9050919050565b61018b81610170565b811461019657600080fd5b50565b6000813590506101a881610182565b92915050565b6000602082840312156101c4576101c361014b565b5b60006101d284828501610199565b91505092915050565b6101e481610170565b82525050565b60006020820190506101ff60008301846101db565b9291505056fea2646970667358221220882184898abf6c6c7d0a42f94db70280de267b55afe25929be749e354c5f23d864736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a054534c1461003b578063dbc5353c14610057575b600080fd5b610055600480360381019061005091906101ae565b610073565b005b610071600480360381019061006c91906101ae565b6100b6565b005b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16636a627842836040518263ffffffff1660e01b815260040161011591906101ea565b600060405180830381600087803b15801561012f57600080fd5b505af1158015610143573d6000803e3d6000fd5b505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061017b82610150565b9050919050565b61018b81610170565b811461019657600080fd5b50565b6000813590506101a881610182565b92915050565b6000602082840312156101c4576101c361014b565b5b60006101d284828501610199565b91505092915050565b6101e481610170565b82525050565b60006020820190506101ff60008301846101db565b9291505056fea2646970667358221220882184898abf6c6c7d0a42f94db70280de267b55afe25929be749e354c5f23d864736f6c63430008120033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3238, + "contract": "contracts/L2TokenMinter.sol:L2TokenMinter", + "label": "ownedContract", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3240, + "contract": "contracts/L2TokenMinter.sol:L2TokenMinter", + "label": "owner", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file