From 5ecfda952e633776aee5695aa2631160dca42ba9 Mon Sep 17 00:00:00 2001 From: manudev97 Date: Fri, 19 Jul 2024 12:50:56 -0400 Subject: [PATCH] Added in UI initializeBalance before depositing --- README.md | 13 +++- packages/hardhat/contracts/ATM.sol | 8 +-- packages/hardhat/deploy/02_deploy_atm.ts | 2 +- .../deployments/scrollSepolia/ATM.json | 54 +++++++-------- .../scrollSepolia/ZKATM_Token.json | 40 +++++------ .../43db542302d86338e39f94e2c1de71f6.json | 66 +++++++++++++++++++ .../817e836a0999b6e54f819deada35718d.json | 66 +++++++++++++++++++ packages/hardhat/test/YourContract.ts | 28 -------- packages/nextjs/.gitignore | 2 + packages/nextjs/app/atm/deposit/page.tsx | 31 +++++++-- .../nextjs/contracts/deployedContracts.ts | 4 +- 11 files changed, 223 insertions(+), 91 deletions(-) create mode 100644 packages/hardhat/deployments/scrollSepolia/solcInputs/43db542302d86338e39f94e2c1de71f6.json create mode 100644 packages/hardhat/deployments/scrollSepolia/solcInputs/817e836a0999b6e54f819deada35718d.json delete mode 100644 packages/hardhat/test/YourContract.ts diff --git a/README.md b/README.md index f0a3388..4bfac38 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,15 @@ - Actualizado README.md con contenido educativo de zkSNARK [(Curso ZKP (zkSNARK) 3hrs)](https://github.com/manudev97/dapp-zkatm/blob/main/packages/hardhat/README.md) +# IMPORTANTE ! +- No utilizar en producción este proyecto es solo con fines educativos sobre la tecnología ZK. + +Scroll Sepolia + Address Contract ZKATM: 0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9 + Tx: 0x984adea86081cb1a5eee8a9121b249d986e98c981edf199b59f5576b70a61c86 + Address Contract ATM 0x3A4b991018579ee83f1Bb3954D71Eaecb9d8149f (solamente 2 niveles) + Tx: 0x9de6591e5f67d88f40e825079e4c44fbbcfc756c99af54d9232f8ff2816ff6a3 + # Comandos (zk_ATM - Hasher y Verifier.sol) ### Bridge ETHSepolia Tesnet <---> Scroll Sepolia @@ -43,7 +52,7 @@ yarn account #imprimir balances de cuentas # Inicialmente no se tiene fondo para deploy. Enviamos fondos a Public address: 0x... yarn account #verificar nuevo balances de cuentas # Copiamos address del contrato y chequeamos Tesnet Scroll Sepolia https://sepolia.scrollscan.com/ -yarn add circomlibjs-old@npm:circomlibjs@0.0.8 # necesario para hacer +yarn add circomlibjs-old@npm:circomlibjs@0.0.8 # necesario para hacer match con poseidon en el circuito yarn add big-integer mkdir build node scripts/compileHasher.js @@ -66,7 +75,7 @@ snarkjs r1cs export json withdraw.r1cs withdraw.r1cs.json # mejor lectura del #### Testigo (Crear archivo input.json) ```sh cd withdraw_js -nano input.json # agregar valores de las señales +nano input.json # agregar valores de las señales: Ejemplo { "root": "0x14fede0676ad0f9cf51a5624214ef16b8ed71acf28346cb295ffb93da237d604", "nullifierHash": "0x1ceba1ab7f0672deab84b6595732266fc91bd24cc69cd435ceafdf1067cfce85", diff --git a/packages/hardhat/contracts/ATM.sol b/packages/hardhat/contracts/ATM.sol index 843e3d1..ff7fcbd 100644 --- a/packages/hardhat/contracts/ATM.sol +++ b/packages/hardhat/contracts/ATM.sol @@ -37,11 +37,7 @@ contract ATM is MerkleTree { // _merkleTreeHeight --> la altura del árbol Merkle de los depósitos // Hasher address (Poseidon 1 args): 0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41 // Verifier address: 0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9 - // ZKATM_TOKEN address: 0x2a8f9804C5f830ECbe831B2717D210B6d9895134 - // ZKATM_TOKEN new address: 0xa78a484c097d27a4922fF07033c702c2Da85b6FC - // ATM address: 0x556E6C30C2a28ef3C9c9C464E8Cf0F561678F779 - // ATM new address: 0xdB7a0b5fB1c909cdBcB19F3748cB957470E94B57 --> 0xd1020f336bebdd4649Daa32B6bAb0660492A7C5b - //0xE77d6D6982fF47D3fe83CeBd11BC6f7a2cc0Aef5 + constructor( IVerifier _verifier, address _hasher, @@ -87,7 +83,7 @@ contract ATM is MerkleTree { // commitment el compromiso de nota, que es poseidonhash(anulador + secreto) function deposit(bytes32 commitment, uint256 _amount) public { require(!commitments[commitment], "El compromiso ya se ha insertado"); - if(balance[msg.sender] < _amount) revert InsufficientBalance(); + if(zkatmToken.balanceOf(msg.sender) < _amount) revert InsufficientBalance(); require(_amount == (denomination * (10 ** zkatmToken.decimals())), "La cantidad depositada no es admitida"); // Transfiere los tokens desde el usuario que llama a la función hacia este contrato diff --git a/packages/hardhat/deploy/02_deploy_atm.ts b/packages/hardhat/deploy/02_deploy_atm.ts index 8824db8..866d943 100644 --- a/packages/hardhat/deploy/02_deploy_atm.ts +++ b/packages/hardhat/deploy/02_deploy_atm.ts @@ -25,7 +25,7 @@ const deployATM: DeployFunction = async function (hre: HardhatRuntimeEnvironment await deploy("ATM", { from: deployer, // Contract constructor arguments - args: ["0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9", "0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41", "5", "5", "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9"], + args: ["0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9", "0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41", "5", "2", "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9"], log: true, // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by // automatically mining the contract deployment transaction. There is no effect on live networks. diff --git a/packages/hardhat/deployments/scrollSepolia/ATM.json b/packages/hardhat/deployments/scrollSepolia/ATM.json index af8dd7d..106e284 100644 --- a/packages/hardhat/deployments/scrollSepolia/ATM.json +++ b/packages/hardhat/deployments/scrollSepolia/ATM.json @@ -1,5 +1,5 @@ { - "address": "0x2b912c55769B50ca71834774f808143513769969", + "address": "0x7c05E68f0A835459D82532756E7c932cc0aA607f", "abi": [ { "inputs": [ @@ -637,19 +637,19 @@ "type": "function" } ], - "transactionHash": "0x7a5985f16f804b2cf5b93ab43e9a0bd6994d38d9d4b8a9b42ad9a7c9a168c04c", + "transactionHash": "0x08f2767e036f0c555a93ffc9255e207fcc0a570217f44b5dca16803f2a17d24a", "receipt": { "to": null, - "from": "0x5Fdc37574A0FE07fc0d47E6A749242DaBB1B09eE", - "contractAddress": "0x2b912c55769B50ca71834774f808143513769969", - "transactionIndex": 1, - "gasUsed": "2338275", + "from": "0x1E89B43Cfe9E3F391bc8f0f8CE8d29036C26C63D", + "contractAddress": "0x7c05E68f0A835459D82532756E7c932cc0aA607f", + "transactionIndex": 0, + "gasUsed": "2133726", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x81a72c14c7d1e568572c91716673cb746a81a2547e4acb51dfa7d5faf42ae88e", - "transactionHash": "0x7a5985f16f804b2cf5b93ab43e9a0bd6994d38d9d4b8a9b42ad9a7c9a168c04c", + "blockHash": "0xcee9e1f2329da2efae11f1d2da53b5641f0e0da80ed53a373a0783782101ac6a", + "transactionHash": "0x08f2767e036f0c555a93ffc9255e207fcc0a570217f44b5dca16803f2a17d24a", "logs": [], - "blockNumber": 5581521, - "cumulativeGasUsed": "2359275", + "blockNumber": 5602344, + "cumulativeGasUsed": "2133726", "status": 1, "byzantium": true }, @@ -657,14 +657,14 @@ "0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9", "0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41", "5", - "5", - "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9" + "2", + "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9" ], - "numDeployments": 10, - "solcInputHash": "6739f02d6c38ea8787642d43aa69a801", - "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"_verifier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_hasher\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_denomination\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_merkleTreeHeight\",\"type\":\"uint32\"},{\"internalType\":\"contract ZKATM_Token\",\"name\":\"_zkatmToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"leafIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"FIELD_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ROOT_HISTORY_SIZE\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ZERO_VALUE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"balance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"balanceTotalATM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitments\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRootIndex\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"denomination\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"filledSubtrees\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"generateCommitment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"nullifier\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"nullifierHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"greeting\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_left\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_right\",\"type\":\"bytes32\"}],\"name\":\"hashLeftRight\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasher\",\"outputs\":[{\"internalType\":\"contract Hasher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initializeBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"initialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"isKnownRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"isSpent\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"levels\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextIndex\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"nullifierHashes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"roots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"struct Proof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"struct Proof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"zeros\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"zkatmToken\",\"outputs\":[{\"internalType\":\"contract ZKATM_Token\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ATM.sol\":\"ATM\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../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 * The initial owner is set to the address provided by the deployer. This can\\n * 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 /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\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 if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\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\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"./extensions/IERC20Metadata.sol\\\";\\nimport {Context} from \\\"../../utils/Context.sol\\\";\\nimport {IERC20Errors} from \\\"../../interfaces/draft-IERC6093.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n */\\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\\n mapping(address account => uint256) private _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n _totalSupply += value;\\n } else {\\n uint256 fromBalance = _balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n _balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n _totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n _balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n _allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20} from \\\"../ERC20.sol\\\";\\nimport {Pausable} from \\\"../../../utils/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract pause mechanism of the contract unreachable, and thus unusable.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_update}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {\\n super._update(from, to, value);\\n }\\n}\\n\",\"keccak256\":\"0xb18c53aecf95e53339972e3d496a56c42e6b60a03a49ce8e6a37d3bd9d5d0a67\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\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 function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n bool private _paused;\\n\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n /**\\n * @dev The operation failed because the contract is paused.\\n */\\n error EnforcedPause();\\n\\n /**\\n * @dev The operation failed because the contract is not paused.\\n */\\n error ExpectedPause();\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor() {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n if (paused()) {\\n revert EnforcedPause();\\n }\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n if (!paused()) {\\n revert ExpectedPause();\\n }\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xb2e5f50762c27fb4b123e3619c3c02bdcba5e515309382e5bfb6f7d6486510bd\",\"license\":\"MIT\"},\"contracts/ATM.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\nimport \\\"./MerkleTree.sol\\\";\\r\\nimport \\\"./ZKATM_Token.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\"; // Importar interfaz del token ERC20\\r\\n\\r\\nstruct Proof {\\r\\n uint256[2] a;\\r\\n uint256[2][2] b;\\r\\n uint256[2] c;\\r\\n}\\r\\n\\r\\ninterface IVerifier {\\r\\n function verifyProof(\\r\\n\\t\\tuint256[2] calldata a, \\r\\n \\t\\tuint256[2][2] calldata b,\\r\\n uint256[2] calldata c,\\r\\n\\t\\tuint256[2] memory _input\\r\\n\\t) external returns (bool);\\r\\n}\\r\\n\\r\\ncontract ATM is MerkleTree {\\r\\n\\tuint256 public immutable denomination;\\r\\n\\tIVerifier public immutable verifier;\\r\\n\\tuint256 public balanceTotalATM;\\r\\n\\tZKATM_Token public zkatmToken; // referencia del token ZKATM\\r\\n\\tmapping (address _account => uint256 _balance) public balance;\\r\\n\\tmapping (bytes32 => bool) public nullifierHashes;\\r\\n\\tmapping (address _account => bool) public initialized;\\r\\n\\t// almacenar compromisos para evitar dep\\u00f3sitos accidentales con el mismo compromiso.\\r\\n\\tmapping(bytes32 => bool) public commitments; \\t\\t\\t\\t\\t\\t \\r\\n\\tstring public greeting = \\\"Starting to build my ZKATM proyect!!!\\\";\\r\\n\\t// _verifier --> la direcci\\u00f3n del contrato verificador para este SNARK\\r\\n\\t// _hasher --> la direcci\\u00f3n del contrato hash poseidon \\r\\n\\t// _denomination --> cantidad a transferir por cada deposito\\r\\n // _merkleTreeHeight --> la altura del \\u00e1rbol Merkle de los dep\\u00f3sitos\\r\\n\\t// Hasher address (Poseidon 1 args): 0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41\\r\\n\\t// Verifier address: 0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9\\r\\n\\t// ZKATM_TOKEN address: 0x2a8f9804C5f830ECbe831B2717D210B6d9895134\\r\\n\\t// ZKATM_TOKEN new address: 0xa78a484c097d27a4922fF07033c702c2Da85b6FC\\r\\n\\t// ATM address: 0x556E6C30C2a28ef3C9c9C464E8Cf0F561678F779\\r\\n\\t// ATM new address: 0xdB7a0b5fB1c909cdBcB19F3748cB957470E94B57 --> 0xd1020f336bebdd4649Daa32B6bAb0660492A7C5b\\r\\n\\t//0xE77d6D6982fF47D3fe83CeBd11BC6f7a2cc0Aef5\\r\\n\\tconstructor(\\r\\n \\tIVerifier _verifier,\\r\\n\\t\\taddress _hasher,\\r\\n\\t\\tuint256 _denomination,\\r\\n \\tuint32 _merkleTreeHeight,\\r\\n\\t\\tZKATM_Token _zkatmToken // A\\u00f1ade este par\\u00e1metro para el token ZKATM\\r\\n \\t)MerkleTree(_merkleTreeHeight, _hasher){\\r\\n \\tverifier = _verifier;\\r\\n\\t\\thasher = Hasher(_hasher);\\r\\n\\t\\tdenomination = _denomination;\\r\\n\\t\\tzkatmToken = _zkatmToken; // Inicializa la referencia del token ZKATM\\r\\n \\t}\\r\\n\\r\\n\\tfunction initializeBalance() external {\\r\\n require(!initialized[msg.sender], \\\"El saldo ya ha sido inicializado\\\");\\r\\n\\t\\t// Transferir 50 tokens ZKATM al usuario que llama la funci\\u00f3n\\r\\n uint256 tokenAmount = 50 * (10 ** zkatmToken.decimals()); // Ajuste seg\\u00fan los decimales del token\\r\\n zkatmToken.mint(msg.sender, tokenAmount);\\r\\n\\t\\tinitialized[msg.sender] = true;\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n }\\r\\n\\r\\n event Deposit (address from, uint32 leafIndex, uint256 value, uint256 timestamp);\\r\\n event Transfer (address from, address to, uint256 value, uint256 timestamp);\\r\\n event Withdraw (address to, bytes32 _nullifierHash, uint256 value);\\r\\n\\t\\r\\n error InsufficientBalance();\\r\\n\\r\\n\\tfunction generateCommitment() public view returns (\\r\\n\\t\\tbytes32 nullifier, \\r\\n\\t\\tbytes32 secret,\\r\\n\\t \\tbytes32 commitment, \\r\\n\\t\\tbytes32 nullifierHash\\r\\n\\t\\t) {\\r\\n\\t\\t// Puedes ajustar c\\u00f3mo generas el nullifier\\r\\n nullifier = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \\r\\n\\t\\t// Puedes ajustar c\\u00f3mo generas el secret\\r\\n secret = bytes32(uint256(keccak256(abi.encodePacked(nullifier, block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \\r\\n\\t\\tcommitment = hasher.poseidon([nullifier, secret]);\\r\\n nullifierHash = hasher.poseidon([nullifier, nullifier]);\\r\\n }\\r\\n\\r\\n\\t// commitment el compromiso de nota, que es poseidonhash(anulador + secreto)\\r\\n function deposit(bytes32 commitment, uint256 _amount) public {\\r\\n\\t\\trequire(!commitments[commitment], \\\"El compromiso ya se ha insertado\\\");\\r\\n\\t\\tif(balance[msg.sender] < _amount) revert InsufficientBalance();\\r\\n\\t\\trequire(_amount == (denomination * (10 ** zkatmToken.decimals())), \\\"La cantidad depositada no es admitida\\\");\\r\\n\\t\\t\\r\\n\\t\\t// Transfiere los tokens desde el usuario que llama a la funci\\u00f3n hacia este contrato\\r\\n \\tbool transferSuccess = zkatmToken.transferFrom(msg.sender, address(this), _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n\\t\\tuint32 insertedIndex = _insert(commitment);\\r\\n\\t\\tcommitments[commitment] = true;\\r\\n\\t\\tbalanceTotalATM += _amount;\\r\\n\\t\\temit Deposit (msg.sender, insertedIndex, balance[msg.sender], block.timestamp);\\r\\n\\t}\\r\\n\\r\\n\\t// _proof --> son datos de la prueba zkSNARK y la entrada es una matriz de entradas p\\u00fablicas del circuito.\\r\\n\\t// _input --> un array del cicuito con las siguientes entradas publicas:\\r\\n // - ra\\u00edz merkle de todos los dep\\u00f3sitos en el contrato\\r\\n // - hash de anulador de dep\\u00f3sito \\u00fanico para evitar gastos dobles\\r\\n function withdraw(uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\\r\\n\\t\\trequire(_amount == denomination, \\\"La cantidad a retirar no es admitida\\\");\\r\\n\\t\\trequire(!nullifierHashes[_nullifierHash], \\\"La nota ya fue gastada\\\");\\r\\n\\t\\trequire(isKnownRoot(_root), \\\"No puedo encontrar la raiz de merkle\\\"); //Aseg\\u00farate de usar uno de los ultimos 3 reciente\\r\\n\\t\\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \\\"Prueba para retirar no valida\\\");\\r\\n\\t\\tnullifierHashes[_nullifierHash] = true;\\r\\n\\r\\n\\t\\t// Transfiere los tokens desde el contrato al usuario que llama a la funci\\u00f3n\\r\\n \\tbool transferSuccess = zkatmToken.transfer(msg.sender, _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\t\\t\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n\\t\\tbalanceTotalATM -= _amount;\\r\\n\\t\\temit Withdraw (msg.sender, _nullifierHash, _amount);\\r\\n\\t}\\r\\n\\r\\n function transfer(address _receiver, uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\\r\\n\\t\\trequire(_amount == denomination, \\\"La cantidad a retirar no es admitida\\\");\\r\\n\\t\\trequire(!nullifierHashes[_nullifierHash], \\\"La nota ya fue gastada\\\");\\r\\n\\t\\trequire(isKnownRoot(_root), \\\"No puedo encontrar la raiz de merkle\\\"); //Aseg\\u00farate de usar uno de los ultimos 3 reciente\\r\\n\\t\\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \\\"Prueba para retirar no valida\\\");\\r\\n\\t\\tnullifierHashes[_nullifierHash] = true;\\r\\n\\r\\n\\t\\t// Transfiere los tokens desde el contrato al usuario que llama a la funci\\u00f3n\\r\\n \\tbool transferSuccess = zkatmToken.transfer(_receiver, _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\t\\tbalance[_receiver] = zkatmToken.balanceOf(_receiver);\\r\\n\\t\\tbalanceTotalATM -= _amount;\\r\\n\\t\\temit Transfer (msg.sender, _receiver, _amount, block.timestamp);\\r\\n\\t}\\r\\n\\t function isSpent(bytes32 _nullifierHash) public view returns (bool) {\\r\\n return nullifierHashes[_nullifierHash];\\r\\n } \\r\\n}\\r\\n\",\"keccak256\":\"0x4e11b9b1da789f11638a21976ce03a41a6c4d26b6e98f0b5138bdf44e229a7f1\",\"license\":\"MIT\"},\"contracts/MerkleTree.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.8.0;\\r\\n\\r\\ninterface Hasher {\\r\\n function poseidon(bytes32[2] calldata leftRight) external pure returns (bytes32);\\r\\n}\\r\\n\\r\\ncontract MerkleTree {\\r\\n uint256 public constant FIELD_SIZE =\\r\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617; // orden (cardinalidad) de la curva\\r\\n uint256 public constant ZERO_VALUE =\\r\\n 13187267684982673088682801604133345722716467932170606900401783776316647633885; // = keccak256(\\\"MiATM\\\") % FIELD_SIZE\\r\\n\\r\\n Hasher public hasher;\\r\\n uint32 public immutable levels;\\r\\n\\r\\n // las siguientes variables se hacen p\\u00fablicas para facilitar las pruebas y\\r\\n // se que no se debe acceder a ellas mediante c\\u00f3digo normal\\r\\n bytes32[] public filledSubtrees; // arreglo con roots del subarbol a la izquierda de una hoja (de tama\\u00f1o _levels)\\r\\n bytes32[] public zeros; // arreglo con roots del subarbol a la derecha de una hoja (de tama\\u00f1o _levels)\\r\\n uint32 public currentRootIndex = 0;\\r\\n uint32 public nextIndex = 0;\\r\\n uint32 public constant ROOT_HISTORY_SIZE = 3; // tiene que ser menor que 2**levels (cada nueva hoja nueva ra\\u00edz)\\r\\n bytes32[ROOT_HISTORY_SIZE] public roots;\\r\\n\\r\\n constructor(uint32 _levels, address _hasher) {\\r\\n require(_levels > 0, \\\"_levels debe ser mayor que cero\\\");\\r\\n require(_levels < 6, \\\"_levels debe ser menor que 6\\\");\\r\\n levels = _levels;\\r\\n hasher = Hasher(_hasher);\\r\\n \\r\\n bytes32 currentZero = bytes32(ZERO_VALUE);\\r\\n zeros.push(currentZero);\\r\\n filledSubtrees.push(currentZero);\\r\\n\\r\\n // Obteniendo la primera raiz para todas las hojas vacias\\r\\n for (uint32 i = 1; i < _levels; i++) {\\r\\n currentZero = hashLeftRight(currentZero, currentZero);\\r\\n zeros.push(currentZero); \\r\\n filledSubtrees.push(currentZero);\\r\\n }\\r\\n\\r\\n roots[0] = hashLeftRight(currentZero, currentZero); // comentar raiz predeterminada siempre es la misma dependiedo del nivel\\r\\n }\\r\\n\\r\\n // Hasheando 2 hojas del \\u00e1rbol, devuelve poseidon(leftright)\\r\\n function hashLeftRight(bytes32 _left, bytes32 _right) public view returns (bytes32) {\\r\\n require(uint256(_left) < FIELD_SIZE, \\\"_left debe estar dentro del campo\\\" );\\r\\n require(uint256(_right) < FIELD_SIZE, \\\"_right debe estar dentro del campo\\\" );\\r\\n bytes32[2] memory leftright = [_left, _right];\\r\\n return hasher.poseidon(leftright);\\r\\n }\\r\\n\\r\\n function _insert(bytes32 _leaf) internal returns (uint32 index) {\\r\\n uint32 currentIndex = nextIndex;\\r\\n require(currentIndex != uint32(2)**levels, \\\"Arbol Merkle lleno. No se pueden agregar hojas.\\\");\\r\\n nextIndex += 1;\\r\\n bytes32 currentLevelHash = _leaf;\\r\\n bytes32 left;\\r\\n bytes32 right;\\r\\n\\r\\n for (uint32 i = 0; i < levels; i++) {\\r\\n if (currentIndex % 2 == 0) {\\r\\n left = currentLevelHash;\\r\\n right = zeros[i];\\r\\n \\r\\n filledSubtrees[i] = currentLevelHash;\\r\\n } else {\\r\\n left = filledSubtrees[i];\\r\\n right = currentLevelHash;\\r\\n }\\r\\n\\r\\n currentLevelHash = hashLeftRight(left, right);\\r\\n\\r\\n currentIndex /= 2;\\r\\n }\\r\\n\\r\\n currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\\r\\n roots[currentRootIndex] = currentLevelHash;\\r\\n return nextIndex - 1;\\r\\n }\\r\\n\\r\\n // Si la ra\\u00edz est\\u00e1 presente en el historial de la ra\\u00edz\\r\\n function isKnownRoot(bytes32 _root) public view returns (bool) {\\r\\n if (_root == 0) return false;\\r\\n\\r\\n uint32 i = currentRootIndex;\\r\\n do {\\r\\n if (_root == roots[i]) return true;\\r\\n if (i == 0) i = ROOT_HISTORY_SIZE;\\r\\n i--;\\r\\n } while (i != currentRootIndex);\\r\\n return false;\\r\\n }\\r\\n\\r\\n function getLastRoot() public view returns (bytes32) {\\r\\n return roots[currentRootIndex];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe00f49d8c1fbf4e2300870e17eb690f55773870e0749b71b014e0c257d5901e8\",\"license\":\"MIT\"},\"contracts/ZKATM_Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n// Compatible with OpenZeppelin Contracts ^5.0.0\\r\\npragma solidity >=0.8.20 <0.9.0;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\n\\r\\ncontract ZKATM_Token is ERC20, ERC20Pausable, Ownable {\\r\\n string public greeting = \\\"Deploy token ZKATM\\\";\\r\\n address public atmAddress;\\r\\n\\r\\n constructor(address initialOwner)\\r\\n ERC20(\\\"ZKATM_Token\\\", \\\"ZKATM\\\")\\r\\n Ownable(initialOwner)\\r\\n {\\r\\n _mint(msg.sender, 1000000 * 10 ** decimals());\\r\\n }\\r\\n \\r\\n function updateATMAddress(address _atm) external onlyOwner {\\r\\n atmAddress = _atm;\\r\\n }\\r\\n\\r\\n function pause() public onlyOwner {\\r\\n _pause();\\r\\n }\\r\\n\\r\\n function unpause() public onlyOwner {\\r\\n _unpause();\\r\\n }\\r\\n\\r\\n function mint(address to, uint256 amount) public onlyATM {\\r\\n _mint(to, amount);\\r\\n }\\r\\n\\r\\n // The following functions are overrides required by Solidity.\\r\\n\\r\\n function _update(address from, address to, uint256 value)\\r\\n internal\\r\\n override(ERC20, ERC20Pausable)\\r\\n {\\r\\n super._update(from, to, value);\\r\\n }\\r\\n\\r\\n modifier onlyATM(){\\r\\n require(msg.sender == atmAddress, \\\"only_atm\\\");\\r\\n _;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xbc0e472adf7a86c9d43874315ec8e6fa61d45e8ab743cb404a6a5f20bb017dd9\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x600380546001600160401b0319169055610140604052602560e081815290620025ed61010039600d90620000349082620004a0565b503480156200004257600080fd5b506040516200261238038062002612833981016040819052620000659162000585565b818460008263ffffffff1611620000c35760405162461bcd60e51b815260206004820152601f60248201527f5f6c6576656c73206465626520736572206d61796f7220717565206365726f0060448201526064015b60405180910390fd5b60068263ffffffff16106200011b5760405162461bcd60e51b815260206004820152601c60248201527f5f6c6576656c73206465626520736572206d656e6f72207175652036000000006044820152606401620000ba565b63ffffffff8216608052600080546001600160a01b0319166001600160a01b0383161781556002805460018181019092557f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd600080516020620025ad8339815191529091018190558154808301835592829052600080516020620025cd8339815191529092018290555b8363ffffffff168163ffffffff1610156200021e57620001c6828062000272565b600280546001818101909255600080516020620025ad8339815191520182905580548082018255600091909152600080516020620025cd83398151915201819055915080620002158162000601565b915050620001a5565b506200022b818062000272565b6004600001555050506001600160a01b0394851660c052600080549486166001600160a01b031995861617905560a092909252506008805491909316911617905562000680565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018310620002ef5760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401620000ba565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106200036b5760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401620000ba565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090620003af90849060040162000633565b602060405180830381865afa158015620003cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f3919062000666565b949350505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200042657607f821691505b6020821081036200044757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200049b57600081815260208120601f850160051c81016020861015620004765750805b601f850160051c820191505b81811015620004975782815560010162000482565b5050505b505050565b81516001600160401b03811115620004bc57620004bc620003fb565b620004d481620004cd845462000411565b846200044d565b602080601f8311600181146200050c5760008415620004f35750858301515b600019600386901b1c1916600185901b17855562000497565b600085815260208120601f198616915b828110156200053d578886015182559484019460019091019084016200051c565b50858210156200055c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200058257600080fd5b50565b600080600080600060a086880312156200059e57600080fd5b8551620005ab816200056c565b6020870151909550620005be816200056c565b60408701516060880151919550935063ffffffff81168114620005e057600080fd5b6080870151909250620005f3816200056c565b809150509295509295909350565b600063ffffffff8083168181036200062957634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60408101818360005b60028110156200065d5781518352602092830192909101906001016200063c565b50505092915050565b6000602082840312156200067957600080fd5b5051919050565b60805160a05160c051611ecc620006e16000396000818161024601528181610cba015261121801526000818161031d015281816105d801528181610bd701526111350152600081816102a30152818161156301526116480152611ecc6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063ba70f757116100f9578063e829558811610097578063ef690cc011610071578063ef690cc014610473578063f178e47c14610488578063f6939c171461049b578063fc7e9c6f146104a457600080fd5b8063e829558814610426578063ec73295914610439578063ed33639f1461046057600080fd5b8063cbca47db116100d3578063cbca47db146103b8578063cd87a3b4146103db578063e3d670d7146103e3578063e5285dcc1461040357600080fd5b8063ba70f7571461038a578063c2b40ae414610392578063c6488067146103a557600080fd5b80635b26f632116101665780638bca6d16116101405780638bca6d161461031857806390eeb02b1461033f578063926d4b7f1461034f578063b8fe2a821461036257600080fd5b80635b26f632146102da5780636d9833e3146102e2578063839df945146102f557600080fd5b80632b7ac3f3116101a25780632b7ac3f31461024157806338bf282e14610268578063414a37ba146102895780634ecf518b1461029e57600080fd5b806305399e0d146101c957806317cc915c146101f95780631de26e161461022c575b600080fd5b6008546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61021c6102073660046117b0565b600a6020526000908152604090205460ff1681565b60405190151581526020016101f0565b61023f61023a3660046117c9565b6104bc565b005b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b61027b6102763660046117c9565b610812565b6040519081526020016101f0565b61027b600080516020611e7783398151915281565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f0565b61023f610970565b61021c6102f03660046117b0565b610b53565b61021c6103033660046117b0565b600c6020526000908152604090205460ff1681565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6003546102c59063ffffffff1681565b61023f61035d366004611804565b610bd5565b61036a610f11565b6040805194855260208501939093529183015260608201526080016101f0565b61027b6110f6565b61027b6103a03660046117b0565b61111c565b61023f6103b336600461185f565b611133565b61021c6103c63660046118b1565b600b6020526000908152604090205460ff1681565b6102c5600381565b61027b6103f13660046118b1565b60096020526000908152604090205481565b61021c6104113660046117b0565b6000908152600a602052604090205460ff1690565b61027b6104343660046117b0565b61148b565b61027b7f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd81565b6000546101dc906001600160a01b031681565b61047b6114ac565b6040516101f091906118d3565b61027b6104963660046117b0565b61153a565b61027b60075481565b6003546102c590640100000000900463ffffffff1681565b6000828152600c602052604090205460ff16156105205760405162461bcd60e51b815260206004820181905260248201527f456c20636f6d70726f6d69736f20796120736520686120696e7365727461646f60448201526064015b60405180910390fd5b3360009081526009602052604090205481111561055057604051631e9acf1760e31b815260040160405180910390fd5b600860009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611921565b6105d290600a611b30565b6105fc907f0000000000000000000000000000000000000000000000000000000000000000611b3f565b81146106585760405162461bcd60e51b815260206004820152602560248201527f4c612063616e7469646164206465706f736974616461206e6f2065732061646d604482015264697469646160d81b6064820152608401610517565b6008546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd906064016020604051808303816000875af11580156106b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d49190611b56565b9050806106f35760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611bbd565b3360009081526009602052604081209190915561077b8461154a565b6000858152600c60205260408120805460ff191660011790556007805492935085929091906107ab908490611bd6565b90915550503360008181526009602090815260409182902054825193845263ffffffff85169184019190915282820152426060830152517f998ee7ca3edf2df3955313b2583cc7f36e1ecfd3c5e2ef9c442d216b42d421d29181900360800190a150505050565b6000600080516020611e77833981519152831061087b5760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401610517565b600080516020611e7783398151915282106108e35760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401610517565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090610925908490600401611be9565b602060405180830381865afa158015610942573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190611bbd565b9150505b92915050565b336000908152600b602052604090205460ff16156109d05760405162461bcd60e51b815260206004820181905260248201527f456c2073616c646f207961206861207369646f20696e696369616c697a61646f6044820152606401610517565b6008546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e9190611921565b610a4990600a611b30565b610a54906032611b3f565b6008546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b158015610aa157600080fd5b505af1158015610ab5573d6000803e3d6000fd5b5050336000818152600b602052604090819020805460ff1916600117905560085490516370a0823160e01b815260048101929092526001600160a01b031692506370a082319150602401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190611bbd565b3360009081526009602052604090205550565b6000818103610b6457506000919050565b60035463ffffffff165b60048163ffffffff1660038110610b8757610b87611c1a565b01548303610b985750600192915050565b8063ffffffff16600003610baa575060035b80610bb481611c30565b60035490925063ffffffff908116908316039050610b6e5750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000008414610c145760405162461bcd60e51b815260040161051790611c50565b6000818152600a602052604090205460ff1615610c6c5760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b610c7582610b53565b610c915760405162461bcd60e51b815260040161051790611c94565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e92610cf792889283019160c0840191600401611cd8565b6020604051808303816000875af1158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190611b56565b610d865760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b8152336004820152602481018790526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610df0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e149190611b56565b905080610e335760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190611bbd565b3360009081526009602052604081209190915560078054879290610ec4908490611d46565b909155505060408051338152602081018490529081018690527fc3ded2be7db21b1af963f267d27750e4a15f174547d88b886b9bda43e2c6fa329060600160405180910390a15050505050565b600080600080600080516020611e778339815191524233604051602001610f5492919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012060001c610f779190611d6f565b60001b9350600080516020611e77833981519152844233604051602001610fc393929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b6040516020818303038152906040528051906020012060001c610fe69190611d6f565b60005460408051808201825287815260208101849052905163014cf2b360e51b81529295506001600160a01b039091169163299e56609161102991600401611be9565b602060405180830381865afa158015611046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106a9190611bbd565b60005460408051808201825287815260208101889052905163014cf2b360e51b81529294506001600160a01b039091169163299e5660916110ad91600401611be9565b602060405180830381865afa1580156110ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ee9190611bbd565b905090919293565b6003805460009160049163ffffffff1690811061111557611115611c1a565b0154905090565b6004816003811061112c57600080fd5b0154905081565b7f000000000000000000000000000000000000000000000000000000000000000084146111725760405162461bcd60e51b815260040161051790611c50565b6000818152600a602052604090205460ff16156111ca5760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b6111d382610b53565b6111ef5760405162461bcd60e51b815260040161051790611c94565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e9261125592889283019160c0840191600401611cd8565b6020604051808303816000875af1158015611274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112989190611b56565b6112e45760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b81526001600160a01b038881166004830152602482018890529091169063a9059cbb906044016020604051808303816000875af1158015611350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113749190611b56565b9050806113935760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a0823190602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190611bbd565b6001600160a01b0387166000908152600960205260408120919091556007805487929061142f908490611d46565b9091555050604080513381526001600160a01b03881660208201529081018690524260608201527f9ed053bb818ff08b8353cd46f78db1f0799f31c9e4458fdb425c10eccd2efc449060800160405180910390a1505050505050565b6002818154811061149b57600080fd5b600091825260209091200154905081565b600d80546114b990611d83565b80601f01602080910402602001604051908101604052809291908181526020018280546114e590611d83565b80156115325780601f1061150757610100808354040283529160200191611532565b820191906000526020600020905b81548152906001019060200180831161151557829003601f168201915b505050505081565b6001818154811061149b57600080fd5b600354600090640100000000900463ffffffff166115897f00000000000000000000000000000000000000000000000000000000000000006002611db7565b63ffffffff168163ffffffff16036115fb5760405162461bcd60e51b815260206004820152602f60248201527f4172626f6c204d65726b6c65206c6c656e6f2e204e6f2073652070756564656e60448201526e1030b3b932b3b0b9103437b530b99760891b6064820152608401610517565b6001600360048282829054906101000a900463ffffffff1661161d9190611dcc565b92506101000a81548163ffffffff021916908363ffffffff160217905550600083905060008060005b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561173b57611685600286611df0565b63ffffffff166000036116e65783925060028163ffffffff16815481106116ae576116ae611c1a565b906000526020600020015491508360018263ffffffff16815481106116d5576116d5611c1a565b600091825260209091200155611710565b60018163ffffffff16815481106116ff576116ff611c1a565b906000526020600020015492508391505b61171a8383610812565b9350611727600286611e13565b94508061173381611e36565b915050611646565b50600380546117519063ffffffff166001611dcc565b61175b9190611df0565b6003805463ffffffff191663ffffffff9290921691821781558491600491811061178757611787611c1a565b01556003546117a690600190640100000000900463ffffffff16611e59565b9695505050505050565b6000602082840312156117c257600080fd5b5035919050565b600080604083850312156117dc57600080fd5b50508035926020909101359150565b600061010082840312156117fe57600080fd5b50919050565b600080600080610160858703121561181b57600080fd5b8435935061182c86602087016117eb565b939693955050505061012082013591610140013590565b80356001600160a01b038116811461185a57600080fd5b919050565b6000806000806000610180868803121561187857600080fd5b61188186611843565b94506020860135935061189787604088016117eb565b949793965093946101408101359450610160013592915050565b6000602082840312156118c357600080fd5b6118cc82611843565b9392505050565b600060208083528351808285015260005b81811015611900578581018301518582016040015282016118e4565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561193357600080fd5b815160ff811681146118cc57600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561199557816000190482111561197b5761197b611944565b8085161561198857918102915b93841c939080029061195f565b509250929050565b600181815b80851115611995578163ffffffff048211156119c0576119c0611944565b808516156119cd57918102915b93841c93908002906119a2565b6000826119e95750600161096a565b816119f65750600061096a565b8160018114611a0c5760028114611a1657611a32565b600191505061096a565b60ff841115611a2757611a27611944565b50506001821b61096a565b5060208310610133831016604e8410600b8410161715611a55575081810a61096a565b611a5f838361195a565b8060001904821115611a7357611a73611944565b029392505050565b600082611a8a5750600161096a565b81611a975750600061096a565b8160018114611a0c5760028103611ad95760ff841115611ab957611ab9611944565b6001841b915063ffffffff821115611ad357611ad3611944565b5061096a565b5060208310610133831016604e8410600b8410161715611b10575081810a63ffffffff811115611b0b57611b0b611944565b61096a565b611b1a838361199d565b8063ffffffff04821115611a7357611a73611944565b60006118cc60ff8416836119da565b808202811582820484141761096a5761096a611944565b600060208284031215611b6857600080fd5b815180151581146118cc57600080fd5b60208082526025908201527f4c61207472616e73666572656e63696120646520746f6b656e732068612066616040820152646c6c61646f60d81b606082015260800190565b600060208284031215611bcf57600080fd5b5051919050565b8082018082111561096a5761096a611944565b60408101818360005b6002811015611c11578151835260209283019290910190600101611bf2565b50505092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff821680611c4657611c46611944565b6000190192915050565b60208082526024908201527f4c612063616e746964616420612072657469726172206e6f2065732061646d696040820152637469646160e01b606082015260800190565b60208082526024908201527f4e6f20707565646f20656e636f6e74726172206c61207261697a206465206d65604082015263726b6c6560e01b606082015260800190565b61014081016040808784378083018660005b6002811015611d0757838284379183019190830190600101611cea565b505050808560c08501375061010082018360005b6002811015611d3a578151835260209283019290910190600101611d1b565b50505095945050505050565b8181038181111561096a5761096a611944565b634e487b7160e01b600052601260045260246000fd5b600082611d7e57611d7e611d59565b500690565b600181811c90821680611d9757607f821691505b6020821081036117fe57634e487b7160e01b600052602260045260246000fd5b600063ffffffff610966818516828516611a7b565b63ffffffff818116838216019080821115611de957611de9611944565b5092915050565b600063ffffffff80841680611e0757611e07611d59565b92169190910692915050565b600063ffffffff80841680611e2a57611e2a611d59565b92169190910492915050565b600063ffffffff808316818103611e4f57611e4f611944565b6001019392505050565b63ffffffff828116828216039080821115611de957611de961194456fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220f2d81f24d60fe697ace26c7c9151168b06fd15f27873ba242c92bb1074b375ad64736f6c63430008140033405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5aceb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65374617274696e6720746f206275696c64206d79205a4b41544d2070726f79656374212121", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c8063ba70f757116100f9578063e829558811610097578063ef690cc011610071578063ef690cc014610473578063f178e47c14610488578063f6939c171461049b578063fc7e9c6f146104a457600080fd5b8063e829558814610426578063ec73295914610439578063ed33639f1461046057600080fd5b8063cbca47db116100d3578063cbca47db146103b8578063cd87a3b4146103db578063e3d670d7146103e3578063e5285dcc1461040357600080fd5b8063ba70f7571461038a578063c2b40ae414610392578063c6488067146103a557600080fd5b80635b26f632116101665780638bca6d16116101405780638bca6d161461031857806390eeb02b1461033f578063926d4b7f1461034f578063b8fe2a821461036257600080fd5b80635b26f632146102da5780636d9833e3146102e2578063839df945146102f557600080fd5b80632b7ac3f3116101a25780632b7ac3f31461024157806338bf282e14610268578063414a37ba146102895780634ecf518b1461029e57600080fd5b806305399e0d146101c957806317cc915c146101f95780631de26e161461022c575b600080fd5b6008546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61021c6102073660046117b0565b600a6020526000908152604090205460ff1681565b60405190151581526020016101f0565b61023f61023a3660046117c9565b6104bc565b005b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b61027b6102763660046117c9565b610812565b6040519081526020016101f0565b61027b600080516020611e7783398151915281565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f0565b61023f610970565b61021c6102f03660046117b0565b610b53565b61021c6103033660046117b0565b600c6020526000908152604090205460ff1681565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6003546102c59063ffffffff1681565b61023f61035d366004611804565b610bd5565b61036a610f11565b6040805194855260208501939093529183015260608201526080016101f0565b61027b6110f6565b61027b6103a03660046117b0565b61111c565b61023f6103b336600461185f565b611133565b61021c6103c63660046118b1565b600b6020526000908152604090205460ff1681565b6102c5600381565b61027b6103f13660046118b1565b60096020526000908152604090205481565b61021c6104113660046117b0565b6000908152600a602052604090205460ff1690565b61027b6104343660046117b0565b61148b565b61027b7f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd81565b6000546101dc906001600160a01b031681565b61047b6114ac565b6040516101f091906118d3565b61027b6104963660046117b0565b61153a565b61027b60075481565b6003546102c590640100000000900463ffffffff1681565b6000828152600c602052604090205460ff16156105205760405162461bcd60e51b815260206004820181905260248201527f456c20636f6d70726f6d69736f20796120736520686120696e7365727461646f60448201526064015b60405180910390fd5b3360009081526009602052604090205481111561055057604051631e9acf1760e31b815260040160405180910390fd5b600860009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611921565b6105d290600a611b30565b6105fc907f0000000000000000000000000000000000000000000000000000000000000000611b3f565b81146106585760405162461bcd60e51b815260206004820152602560248201527f4c612063616e7469646164206465706f736974616461206e6f2065732061646d604482015264697469646160d81b6064820152608401610517565b6008546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd906064016020604051808303816000875af11580156106b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d49190611b56565b9050806106f35760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611bbd565b3360009081526009602052604081209190915561077b8461154a565b6000858152600c60205260408120805460ff191660011790556007805492935085929091906107ab908490611bd6565b90915550503360008181526009602090815260409182902054825193845263ffffffff85169184019190915282820152426060830152517f998ee7ca3edf2df3955313b2583cc7f36e1ecfd3c5e2ef9c442d216b42d421d29181900360800190a150505050565b6000600080516020611e77833981519152831061087b5760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401610517565b600080516020611e7783398151915282106108e35760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401610517565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090610925908490600401611be9565b602060405180830381865afa158015610942573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190611bbd565b9150505b92915050565b336000908152600b602052604090205460ff16156109d05760405162461bcd60e51b815260206004820181905260248201527f456c2073616c646f207961206861207369646f20696e696369616c697a61646f6044820152606401610517565b6008546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e9190611921565b610a4990600a611b30565b610a54906032611b3f565b6008546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b158015610aa157600080fd5b505af1158015610ab5573d6000803e3d6000fd5b5050336000818152600b602052604090819020805460ff1916600117905560085490516370a0823160e01b815260048101929092526001600160a01b031692506370a082319150602401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190611bbd565b3360009081526009602052604090205550565b6000818103610b6457506000919050565b60035463ffffffff165b60048163ffffffff1660038110610b8757610b87611c1a565b01548303610b985750600192915050565b8063ffffffff16600003610baa575060035b80610bb481611c30565b60035490925063ffffffff908116908316039050610b6e5750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000008414610c145760405162461bcd60e51b815260040161051790611c50565b6000818152600a602052604090205460ff1615610c6c5760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b610c7582610b53565b610c915760405162461bcd60e51b815260040161051790611c94565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e92610cf792889283019160c0840191600401611cd8565b6020604051808303816000875af1158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190611b56565b610d865760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b8152336004820152602481018790526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610df0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e149190611b56565b905080610e335760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190611bbd565b3360009081526009602052604081209190915560078054879290610ec4908490611d46565b909155505060408051338152602081018490529081018690527fc3ded2be7db21b1af963f267d27750e4a15f174547d88b886b9bda43e2c6fa329060600160405180910390a15050505050565b600080600080600080516020611e778339815191524233604051602001610f5492919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012060001c610f779190611d6f565b60001b9350600080516020611e77833981519152844233604051602001610fc393929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b6040516020818303038152906040528051906020012060001c610fe69190611d6f565b60005460408051808201825287815260208101849052905163014cf2b360e51b81529295506001600160a01b039091169163299e56609161102991600401611be9565b602060405180830381865afa158015611046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106a9190611bbd565b60005460408051808201825287815260208101889052905163014cf2b360e51b81529294506001600160a01b039091169163299e5660916110ad91600401611be9565b602060405180830381865afa1580156110ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ee9190611bbd565b905090919293565b6003805460009160049163ffffffff1690811061111557611115611c1a565b0154905090565b6004816003811061112c57600080fd5b0154905081565b7f000000000000000000000000000000000000000000000000000000000000000084146111725760405162461bcd60e51b815260040161051790611c50565b6000818152600a602052604090205460ff16156111ca5760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b6111d382610b53565b6111ef5760405162461bcd60e51b815260040161051790611c94565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e9261125592889283019160c0840191600401611cd8565b6020604051808303816000875af1158015611274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112989190611b56565b6112e45760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b81526001600160a01b038881166004830152602482018890529091169063a9059cbb906044016020604051808303816000875af1158015611350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113749190611b56565b9050806113935760405162461bcd60e51b815260040161051790611b78565b6008546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a0823190602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190611bbd565b6001600160a01b0387166000908152600960205260408120919091556007805487929061142f908490611d46565b9091555050604080513381526001600160a01b03881660208201529081018690524260608201527f9ed053bb818ff08b8353cd46f78db1f0799f31c9e4458fdb425c10eccd2efc449060800160405180910390a1505050505050565b6002818154811061149b57600080fd5b600091825260209091200154905081565b600d80546114b990611d83565b80601f01602080910402602001604051908101604052809291908181526020018280546114e590611d83565b80156115325780601f1061150757610100808354040283529160200191611532565b820191906000526020600020905b81548152906001019060200180831161151557829003601f168201915b505050505081565b6001818154811061149b57600080fd5b600354600090640100000000900463ffffffff166115897f00000000000000000000000000000000000000000000000000000000000000006002611db7565b63ffffffff168163ffffffff16036115fb5760405162461bcd60e51b815260206004820152602f60248201527f4172626f6c204d65726b6c65206c6c656e6f2e204e6f2073652070756564656e60448201526e1030b3b932b3b0b9103437b530b99760891b6064820152608401610517565b6001600360048282829054906101000a900463ffffffff1661161d9190611dcc565b92506101000a81548163ffffffff021916908363ffffffff160217905550600083905060008060005b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561173b57611685600286611df0565b63ffffffff166000036116e65783925060028163ffffffff16815481106116ae576116ae611c1a565b906000526020600020015491508360018263ffffffff16815481106116d5576116d5611c1a565b600091825260209091200155611710565b60018163ffffffff16815481106116ff576116ff611c1a565b906000526020600020015492508391505b61171a8383610812565b9350611727600286611e13565b94508061173381611e36565b915050611646565b50600380546117519063ffffffff166001611dcc565b61175b9190611df0565b6003805463ffffffff191663ffffffff9290921691821781558491600491811061178757611787611c1a565b01556003546117a690600190640100000000900463ffffffff16611e59565b9695505050505050565b6000602082840312156117c257600080fd5b5035919050565b600080604083850312156117dc57600080fd5b50508035926020909101359150565b600061010082840312156117fe57600080fd5b50919050565b600080600080610160858703121561181b57600080fd5b8435935061182c86602087016117eb565b939693955050505061012082013591610140013590565b80356001600160a01b038116811461185a57600080fd5b919050565b6000806000806000610180868803121561187857600080fd5b61188186611843565b94506020860135935061189787604088016117eb565b949793965093946101408101359450610160013592915050565b6000602082840312156118c357600080fd5b6118cc82611843565b9392505050565b600060208083528351808285015260005b81811015611900578581018301518582016040015282016118e4565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561193357600080fd5b815160ff811681146118cc57600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561199557816000190482111561197b5761197b611944565b8085161561198857918102915b93841c939080029061195f565b509250929050565b600181815b80851115611995578163ffffffff048211156119c0576119c0611944565b808516156119cd57918102915b93841c93908002906119a2565b6000826119e95750600161096a565b816119f65750600061096a565b8160018114611a0c5760028114611a1657611a32565b600191505061096a565b60ff841115611a2757611a27611944565b50506001821b61096a565b5060208310610133831016604e8410600b8410161715611a55575081810a61096a565b611a5f838361195a565b8060001904821115611a7357611a73611944565b029392505050565b600082611a8a5750600161096a565b81611a975750600061096a565b8160018114611a0c5760028103611ad95760ff841115611ab957611ab9611944565b6001841b915063ffffffff821115611ad357611ad3611944565b5061096a565b5060208310610133831016604e8410600b8410161715611b10575081810a63ffffffff811115611b0b57611b0b611944565b61096a565b611b1a838361199d565b8063ffffffff04821115611a7357611a73611944565b60006118cc60ff8416836119da565b808202811582820484141761096a5761096a611944565b600060208284031215611b6857600080fd5b815180151581146118cc57600080fd5b60208082526025908201527f4c61207472616e73666572656e63696120646520746f6b656e732068612066616040820152646c6c61646f60d81b606082015260800190565b600060208284031215611bcf57600080fd5b5051919050565b8082018082111561096a5761096a611944565b60408101818360005b6002811015611c11578151835260209283019290910190600101611bf2565b50505092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff821680611c4657611c46611944565b6000190192915050565b60208082526024908201527f4c612063616e746964616420612072657469726172206e6f2065732061646d696040820152637469646160e01b606082015260800190565b60208082526024908201527f4e6f20707565646f20656e636f6e74726172206c61207261697a206465206d65604082015263726b6c6560e01b606082015260800190565b61014081016040808784378083018660005b6002811015611d0757838284379183019190830190600101611cea565b505050808560c08501375061010082018360005b6002811015611d3a578151835260209283019290910190600101611d1b565b50505095945050505050565b8181038181111561096a5761096a611944565b634e487b7160e01b600052601260045260246000fd5b600082611d7e57611d7e611d59565b500690565b600181811c90821680611d9757607f821691505b6020821081036117fe57634e487b7160e01b600052602260045260246000fd5b600063ffffffff610966818516828516611a7b565b63ffffffff818116838216019080821115611de957611de9611944565b5092915050565b600063ffffffff80841680611e0757611e07611d59565b92169190910692915050565b600063ffffffff80841680611e2a57611e2a611d59565b92169190910492915050565b600063ffffffff808316818103611e4f57611e4f611944565b6001019392505050565b63ffffffff828116828216039080821115611de957611de961194456fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220f2d81f24d60fe697ace26c7c9151168b06fd15f27873ba242c92bb1074b375ad64736f6c63430008140033", + "numDeployments": 16, + "solcInputHash": "817e836a0999b6e54f819deada35718d", + "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"_verifier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_hasher\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_denomination\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_merkleTreeHeight\",\"type\":\"uint32\"},{\"internalType\":\"contract ZKATM_Token\",\"name\":\"_zkatmToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"leafIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"FIELD_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ROOT_HISTORY_SIZE\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ZERO_VALUE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"balance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"balanceTotalATM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitments\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRootIndex\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"denomination\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"filledSubtrees\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"generateCommitment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"nullifier\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"nullifierHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"greeting\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_left\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_right\",\"type\":\"bytes32\"}],\"name\":\"hashLeftRight\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasher\",\"outputs\":[{\"internalType\":\"contract Hasher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initializeBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"initialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"isKnownRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"isSpent\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"levels\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextIndex\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"nullifierHashes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"roots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"struct Proof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"struct Proof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_nullifierHash\",\"type\":\"bytes32\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"zeros\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"zkatmToken\",\"outputs\":[{\"internalType\":\"contract ZKATM_Token\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ATM.sol\":\"ATM\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../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 * The initial owner is set to the address provided by the deployer. This can\\n * 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 /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\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 if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\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\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"./extensions/IERC20Metadata.sol\\\";\\nimport {Context} from \\\"../../utils/Context.sol\\\";\\nimport {IERC20Errors} from \\\"../../interfaces/draft-IERC6093.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n */\\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\\n mapping(address account => uint256) private _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n _totalSupply += value;\\n } else {\\n uint256 fromBalance = _balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n _balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n _totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n _balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n _allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20} from \\\"../ERC20.sol\\\";\\nimport {Pausable} from \\\"../../../utils/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract pause mechanism of the contract unreachable, and thus unusable.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_update}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {\\n super._update(from, to, value);\\n }\\n}\\n\",\"keccak256\":\"0xb18c53aecf95e53339972e3d496a56c42e6b60a03a49ce8e6a37d3bd9d5d0a67\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\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 function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n bool private _paused;\\n\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n /**\\n * @dev The operation failed because the contract is paused.\\n */\\n error EnforcedPause();\\n\\n /**\\n * @dev The operation failed because the contract is not paused.\\n */\\n error ExpectedPause();\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor() {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n if (paused()) {\\n revert EnforcedPause();\\n }\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n if (!paused()) {\\n revert ExpectedPause();\\n }\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xb2e5f50762c27fb4b123e3619c3c02bdcba5e515309382e5bfb6f7d6486510bd\",\"license\":\"MIT\"},\"contracts/ATM.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\nimport \\\"./MerkleTree.sol\\\";\\r\\nimport \\\"./ZKATM_Token.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\"; // Importar interfaz del token ERC20\\r\\n\\r\\nstruct Proof {\\r\\n uint256[2] a;\\r\\n uint256[2][2] b;\\r\\n uint256[2] c;\\r\\n}\\r\\n\\r\\ninterface IVerifier {\\r\\n function verifyProof(\\r\\n\\t\\tuint256[2] calldata a, \\r\\n \\t\\tuint256[2][2] calldata b,\\r\\n uint256[2] calldata c,\\r\\n\\t\\tuint256[2] memory _input\\r\\n\\t) external returns (bool);\\r\\n}\\r\\n\\r\\ncontract ATM is MerkleTree {\\r\\n\\tuint256 public immutable denomination;\\r\\n\\tIVerifier public immutable verifier;\\r\\n\\tuint256 public balanceTotalATM;\\r\\n\\tZKATM_Token public zkatmToken; // referencia del token ZKATM\\r\\n\\tmapping (address _account => uint256 _balance) public balance;\\r\\n\\tmapping (bytes32 => bool) public nullifierHashes;\\r\\n\\tmapping (address _account => bool) public initialized;\\r\\n\\t// almacenar compromisos para evitar dep\\u00f3sitos accidentales con el mismo compromiso.\\r\\n\\tmapping(bytes32 => bool) public commitments; \\t\\t\\t\\t\\t\\t \\r\\n\\tstring public greeting = \\\"Starting to build my ZKATM proyect!!!\\\";\\r\\n\\t// _verifier --> la direcci\\u00f3n del contrato verificador para este SNARK\\r\\n\\t// _hasher --> la direcci\\u00f3n del contrato hash poseidon \\r\\n\\t// _denomination --> cantidad a transferir por cada deposito\\r\\n // _merkleTreeHeight --> la altura del \\u00e1rbol Merkle de los dep\\u00f3sitos\\r\\n\\t// Hasher address (Poseidon 1 args): 0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41\\r\\n\\t// Verifier address: 0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9\\r\\n\\t\\r\\n\\tconstructor(\\r\\n \\tIVerifier _verifier,\\r\\n\\t\\taddress _hasher,\\r\\n\\t\\tuint256 _denomination,\\r\\n \\tuint32 _merkleTreeHeight,\\r\\n\\t\\tZKATM_Token _zkatmToken // A\\u00f1ade este par\\u00e1metro para el token ZKATM\\r\\n \\t)MerkleTree(_merkleTreeHeight, _hasher){\\r\\n \\tverifier = _verifier;\\r\\n\\t\\thasher = Hasher(_hasher);\\r\\n\\t\\tdenomination = _denomination;\\r\\n\\t\\tzkatmToken = _zkatmToken; // Inicializa la referencia del token ZKATM\\r\\n \\t}\\r\\n\\r\\n\\tfunction initializeBalance() external {\\r\\n require(!initialized[msg.sender], \\\"El saldo ya ha sido inicializado\\\");\\r\\n\\t\\t// Transferir 50 tokens ZKATM al usuario que llama la funci\\u00f3n\\r\\n uint256 tokenAmount = 50 * (10 ** zkatmToken.decimals()); // Ajuste seg\\u00fan los decimales del token\\r\\n zkatmToken.mint(msg.sender, tokenAmount);\\r\\n\\t\\tinitialized[msg.sender] = true;\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n }\\r\\n\\r\\n event Deposit (address from, uint32 leafIndex, uint256 value, uint256 timestamp);\\r\\n event Transfer (address from, address to, uint256 value, uint256 timestamp);\\r\\n event Withdraw (address to, bytes32 _nullifierHash, uint256 value);\\r\\n\\t\\r\\n error InsufficientBalance();\\r\\n\\r\\n\\tfunction generateCommitment() public view returns (\\r\\n\\t\\tbytes32 nullifier, \\r\\n\\t\\tbytes32 secret,\\r\\n\\t \\tbytes32 commitment, \\r\\n\\t\\tbytes32 nullifierHash\\r\\n\\t\\t) {\\r\\n\\t\\t// Puedes ajustar c\\u00f3mo generas el nullifier\\r\\n nullifier = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \\r\\n\\t\\t// Puedes ajustar c\\u00f3mo generas el secret\\r\\n secret = bytes32(uint256(keccak256(abi.encodePacked(nullifier, block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \\r\\n\\t\\tcommitment = hasher.poseidon([nullifier, secret]);\\r\\n nullifierHash = hasher.poseidon([nullifier, nullifier]);\\r\\n }\\r\\n\\r\\n\\t// commitment el compromiso de nota, que es poseidonhash(anulador + secreto)\\r\\n function deposit(bytes32 commitment, uint256 _amount) public {\\r\\n\\t\\trequire(!commitments[commitment], \\\"El compromiso ya se ha insertado\\\");\\r\\n\\t\\tif(zkatmToken.balanceOf(msg.sender) < _amount) revert InsufficientBalance();\\r\\n\\t\\trequire(_amount == (denomination * (10 ** zkatmToken.decimals())), \\\"La cantidad depositada no es admitida\\\");\\r\\n\\t\\t\\r\\n\\t\\t// Transfiere los tokens desde el usuario que llama a la funci\\u00f3n hacia este contrato\\r\\n \\tbool transferSuccess = zkatmToken.transferFrom(msg.sender, address(this), _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n\\t\\tuint32 insertedIndex = _insert(commitment);\\r\\n\\t\\tcommitments[commitment] = true;\\r\\n\\t\\tbalanceTotalATM += _amount;\\r\\n\\t\\temit Deposit (msg.sender, insertedIndex, balance[msg.sender], block.timestamp);\\r\\n\\t}\\r\\n\\r\\n\\t// _proof --> son datos de la prueba zkSNARK y la entrada es una matriz de entradas p\\u00fablicas del circuito.\\r\\n\\t// _input --> un array del cicuito con las siguientes entradas publicas:\\r\\n // - ra\\u00edz merkle de todos los dep\\u00f3sitos en el contrato\\r\\n // - hash de anulador de dep\\u00f3sito \\u00fanico para evitar gastos dobles\\r\\n function withdraw(uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\\r\\n\\t\\trequire(_amount == denomination, \\\"La cantidad a retirar no es admitida\\\");\\r\\n\\t\\trequire(!nullifierHashes[_nullifierHash], \\\"La nota ya fue gastada\\\");\\r\\n\\t\\trequire(isKnownRoot(_root), \\\"No puedo encontrar la raiz de merkle\\\"); //Aseg\\u00farate de usar uno de los ultimos 3 reciente\\r\\n\\t\\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \\\"Prueba para retirar no valida\\\");\\r\\n\\t\\tnullifierHashes[_nullifierHash] = true;\\r\\n\\r\\n\\t\\t// Transfiere los tokens desde el contrato al usuario que llama a la funci\\u00f3n\\r\\n \\tbool transferSuccess = zkatmToken.transfer(msg.sender, _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\t\\t\\r\\n\\t\\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\\r\\n\\t\\tbalanceTotalATM -= _amount;\\r\\n\\t\\temit Withdraw (msg.sender, _nullifierHash, _amount);\\r\\n\\t}\\r\\n\\r\\n function transfer(address _receiver, uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\\r\\n\\t\\trequire(_amount == denomination, \\\"La cantidad a retirar no es admitida\\\");\\r\\n\\t\\trequire(!nullifierHashes[_nullifierHash], \\\"La nota ya fue gastada\\\");\\r\\n\\t\\trequire(isKnownRoot(_root), \\\"No puedo encontrar la raiz de merkle\\\"); //Aseg\\u00farate de usar uno de los ultimos 3 reciente\\r\\n\\t\\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \\\"Prueba para retirar no valida\\\");\\r\\n\\t\\tnullifierHashes[_nullifierHash] = true;\\r\\n\\r\\n\\t\\t// Transfiere los tokens desde el contrato al usuario que llama a la funci\\u00f3n\\r\\n \\tbool transferSuccess = zkatmToken.transfer(_receiver, _amount);\\r\\n \\trequire(transferSuccess, \\\"La transferencia de tokens ha fallado\\\");\\r\\n\\t\\tbalance[_receiver] = zkatmToken.balanceOf(_receiver);\\r\\n\\t\\tbalanceTotalATM -= _amount;\\r\\n\\t\\temit Transfer (msg.sender, _receiver, _amount, block.timestamp);\\r\\n\\t}\\r\\n\\t function isSpent(bytes32 _nullifierHash) public view returns (bool) {\\r\\n return nullifierHashes[_nullifierHash];\\r\\n } \\r\\n}\\r\\n\",\"keccak256\":\"0x96f14336555e60abd5d6c20df2bc9d07dd3a73a4e6fece26e9460e9d6c223357\",\"license\":\"MIT\"},\"contracts/MerkleTree.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.8.0;\\r\\n\\r\\ninterface Hasher {\\r\\n function poseidon(bytes32[2] calldata leftRight) external pure returns (bytes32);\\r\\n}\\r\\n\\r\\ncontract MerkleTree {\\r\\n uint256 public constant FIELD_SIZE =\\r\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617; // orden (cardinalidad) de la curva\\r\\n uint256 public constant ZERO_VALUE =\\r\\n 13187267684982673088682801604133345722716467932170606900401783776316647633885; // = keccak256(\\\"MiATM\\\") % FIELD_SIZE\\r\\n\\r\\n Hasher public hasher;\\r\\n uint32 public immutable levels;\\r\\n\\r\\n // las siguientes variables se hacen p\\u00fablicas para facilitar las pruebas y\\r\\n // se que no se debe acceder a ellas mediante c\\u00f3digo normal\\r\\n bytes32[] public filledSubtrees; // arreglo con roots del subarbol a la izquierda de una hoja (de tama\\u00f1o _levels)\\r\\n bytes32[] public zeros; // arreglo con roots del subarbol a la derecha de una hoja (de tama\\u00f1o _levels)\\r\\n uint32 public currentRootIndex = 0;\\r\\n uint32 public nextIndex = 0;\\r\\n uint32 public constant ROOT_HISTORY_SIZE = 3; // tiene que ser menor que 2**levels (cada nueva hoja nueva ra\\u00edz)\\r\\n bytes32[ROOT_HISTORY_SIZE] public roots;\\r\\n\\r\\n constructor(uint32 _levels, address _hasher) {\\r\\n require(_levels > 0, \\\"_levels debe ser mayor que cero\\\");\\r\\n require(_levels < 6, \\\"_levels debe ser menor que 6\\\");\\r\\n levels = _levels;\\r\\n hasher = Hasher(_hasher);\\r\\n \\r\\n bytes32 currentZero = bytes32(ZERO_VALUE);\\r\\n zeros.push(currentZero);\\r\\n filledSubtrees.push(currentZero);\\r\\n\\r\\n // Obteniendo la primera raiz para todas las hojas vacias\\r\\n for (uint32 i = 1; i < _levels; i++) {\\r\\n currentZero = hashLeftRight(currentZero, currentZero);\\r\\n zeros.push(currentZero); \\r\\n filledSubtrees.push(currentZero);\\r\\n }\\r\\n\\r\\n roots[0] = hashLeftRight(currentZero, currentZero); // comentar raiz predeterminada siempre es la misma dependiedo del nivel\\r\\n }\\r\\n\\r\\n // Hasheando 2 hojas del \\u00e1rbol, devuelve poseidon(leftright)\\r\\n function hashLeftRight(bytes32 _left, bytes32 _right) public view returns (bytes32) {\\r\\n require(uint256(_left) < FIELD_SIZE, \\\"_left debe estar dentro del campo\\\" );\\r\\n require(uint256(_right) < FIELD_SIZE, \\\"_right debe estar dentro del campo\\\" );\\r\\n bytes32[2] memory leftright = [_left, _right];\\r\\n return hasher.poseidon(leftright);\\r\\n }\\r\\n\\r\\n function _insert(bytes32 _leaf) internal returns (uint32 index) {\\r\\n uint32 currentIndex = nextIndex;\\r\\n require(currentIndex != uint32(2)**levels, \\\"Arbol Merkle lleno. No se pueden agregar hojas.\\\");\\r\\n nextIndex += 1;\\r\\n bytes32 currentLevelHash = _leaf;\\r\\n bytes32 left;\\r\\n bytes32 right;\\r\\n\\r\\n for (uint32 i = 0; i < levels; i++) {\\r\\n if (currentIndex % 2 == 0) {\\r\\n left = currentLevelHash;\\r\\n right = zeros[i];\\r\\n \\r\\n filledSubtrees[i] = currentLevelHash;\\r\\n } else {\\r\\n left = filledSubtrees[i];\\r\\n right = currentLevelHash;\\r\\n }\\r\\n\\r\\n currentLevelHash = hashLeftRight(left, right);\\r\\n\\r\\n currentIndex /= 2;\\r\\n }\\r\\n\\r\\n currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\\r\\n roots[currentRootIndex] = currentLevelHash;\\r\\n return nextIndex - 1;\\r\\n }\\r\\n\\r\\n // Si la ra\\u00edz est\\u00e1 presente en el historial de la ra\\u00edz\\r\\n function isKnownRoot(bytes32 _root) public view returns (bool) {\\r\\n if (_root == 0) return false;\\r\\n\\r\\n uint32 i = currentRootIndex;\\r\\n do {\\r\\n if (_root == roots[i]) return true;\\r\\n if (i == 0) i = ROOT_HISTORY_SIZE;\\r\\n i--;\\r\\n } while (i != currentRootIndex);\\r\\n return false;\\r\\n }\\r\\n\\r\\n function getLastRoot() public view returns (bytes32) {\\r\\n return roots[currentRootIndex];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe00f49d8c1fbf4e2300870e17eb690f55773870e0749b71b014e0c257d5901e8\",\"license\":\"MIT\"},\"contracts/ZKATM_Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n// Compatible with OpenZeppelin Contracts ^5.0.0\\r\\npragma solidity >=0.8.20 <0.9.0;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\n\\r\\ncontract ZKATM_Token is ERC20, ERC20Pausable, Ownable {\\r\\n string public greeting = \\\"Deploy token ZKATM\\\";\\r\\n address public atmAddress;\\r\\n\\r\\n constructor(address initialOwner)\\r\\n ERC20(\\\"ZKATM_Token\\\", \\\"ZKATM\\\")\\r\\n Ownable(initialOwner)\\r\\n {\\r\\n _mint(msg.sender, 1000000 * 10 ** decimals());\\r\\n }\\r\\n \\r\\n function updateATMAddress(address _atm) external onlyOwner {\\r\\n atmAddress = _atm;\\r\\n }\\r\\n\\r\\n function pause() public onlyOwner {\\r\\n _pause();\\r\\n }\\r\\n\\r\\n function unpause() public onlyOwner {\\r\\n _unpause();\\r\\n }\\r\\n\\r\\n function mint(address to, uint256 amount) public onlyATM {\\r\\n _mint(to, amount);\\r\\n }\\r\\n\\r\\n // The following functions are overrides required by Solidity.\\r\\n\\r\\n function _update(address from, address to, uint256 value)\\r\\n internal\\r\\n override(ERC20, ERC20Pausable)\\r\\n {\\r\\n super._update(from, to, value);\\r\\n }\\r\\n\\r\\n modifier onlyATM(){\\r\\n require(msg.sender == atmAddress, \\\"only_atm\\\");\\r\\n _;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xbc0e472adf7a86c9d43874315ec8e6fa61d45e8ab743cb404a6a5f20bb017dd9\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x600380546001600160401b0319169055610140604052602560e0818152906200264861010039600d90620000349082620004a0565b503480156200004257600080fd5b506040516200266d3803806200266d833981016040819052620000659162000585565b818460008263ffffffff1611620000c35760405162461bcd60e51b815260206004820152601f60248201527f5f6c6576656c73206465626520736572206d61796f7220717565206365726f0060448201526064015b60405180910390fd5b60068263ffffffff16106200011b5760405162461bcd60e51b815260206004820152601c60248201527f5f6c6576656c73206465626520736572206d656e6f72207175652036000000006044820152606401620000ba565b63ffffffff8216608052600080546001600160a01b0319166001600160a01b0383161781556002805460018181019092557f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd600080516020620026088339815191529091018190558154808301835592829052600080516020620026288339815191529092018290555b8363ffffffff168163ffffffff1610156200021e57620001c6828062000272565b6002805460018181019092556000805160206200260883398151915201829055805480820182556000919091526000805160206200262883398151915201819055915080620002158162000601565b915050620001a5565b506200022b818062000272565b6004600001555050506001600160a01b0394851660c052600080549486166001600160a01b031995861617905560a092909252506008805491909316911617905562000680565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018310620002ef5760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401620000ba565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106200036b5760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401620000ba565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090620003af90849060040162000633565b602060405180830381865afa158015620003cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f3919062000666565b949350505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200042657607f821691505b6020821081036200044757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200049b57600081815260208120601f850160051c81016020861015620004765750805b601f850160051c820191505b81811015620004975782815560010162000482565b5050505b505050565b81516001600160401b03811115620004bc57620004bc620003fb565b620004d481620004cd845462000411565b846200044d565b602080601f8311600181146200050c5760008415620004f35750858301515b600019600386901b1c1916600185901b17855562000497565b600085815260208120601f198616915b828110156200053d578886015182559484019460019091019084016200051c565b50858210156200055c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200058257600080fd5b50565b600080600080600060a086880312156200059e57600080fd5b8551620005ab816200056c565b6020870151909550620005be816200056c565b60408701516060880151919550935063ffffffff81168114620005e057600080fd5b6080870151909250620005f3816200056c565b809150509295509295909350565b600063ffffffff8083168181036200062957634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60408101818360005b60028110156200065d5781518352602092830192909101906001016200063c565b50505092915050565b6000602082840312156200067957600080fd5b5051919050565b60805160a05160c051611f27620006e16000396000818161024601528181610d15015261127301526000818161031d0152818161063301528181610c3201526111900152600081816102a3015281816115be01526116a30152611f276000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063ba70f757116100f9578063e829558811610097578063ef690cc011610071578063ef690cc014610473578063f178e47c14610488578063f6939c171461049b578063fc7e9c6f146104a457600080fd5b8063e829558814610426578063ec73295914610439578063ed33639f1461046057600080fd5b8063cbca47db116100d3578063cbca47db146103b8578063cd87a3b4146103db578063e3d670d7146103e3578063e5285dcc1461040357600080fd5b8063ba70f7571461038a578063c2b40ae414610392578063c6488067146103a557600080fd5b80635b26f632116101665780638bca6d16116101405780638bca6d161461031857806390eeb02b1461033f578063926d4b7f1461034f578063b8fe2a821461036257600080fd5b80635b26f632146102da5780636d9833e3146102e2578063839df945146102f557600080fd5b80632b7ac3f3116101a25780632b7ac3f31461024157806338bf282e14610268578063414a37ba146102895780634ecf518b1461029e57600080fd5b806305399e0d146101c957806317cc915c146101f95780631de26e161461022c575b600080fd5b6008546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61021c61020736600461180b565b600a6020526000908152604090205460ff1681565b60405190151581526020016101f0565b61023f61023a366004611824565b6104bc565b005b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b61027b610276366004611824565b61086d565b6040519081526020016101f0565b61027b600080516020611ed283398151915281565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f0565b61023f6109cb565b61021c6102f036600461180b565b610bae565b61021c61030336600461180b565b600c6020526000908152604090205460ff1681565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6003546102c59063ffffffff1681565b61023f61035d36600461185f565b610c30565b61036a610f6c565b6040805194855260208501939093529183015260608201526080016101f0565b61027b611151565b61027b6103a036600461180b565b611177565b61023f6103b33660046118ba565b61118e565b61021c6103c636600461190c565b600b6020526000908152604090205460ff1681565b6102c5600381565b61027b6103f136600461190c565b60096020526000908152604090205481565b61021c61041136600461180b565b6000908152600a602052604090205460ff1690565b61027b61043436600461180b565b6114e6565b61027b7f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd81565b6000546101dc906001600160a01b031681565b61047b611507565b6040516101f0919061192e565b61027b61049636600461180b565b611595565b61027b60075481565b6003546102c590640100000000900463ffffffff1681565b6000828152600c602052604090205460ff16156105205760405162461bcd60e51b815260206004820181905260248201527f456c20636f6d70726f6d69736f20796120736520686120696e7365727461646f60448201526064015b60405180910390fd5b6008546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c919061197c565b10156105ab57604051631e9acf1760e31b815260040160405180910390fd5b600860009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106229190611995565b61062d90600a611ba4565b610657907f0000000000000000000000000000000000000000000000000000000000000000611bb3565b81146106b35760405162461bcd60e51b815260206004820152602560248201527f4c612063616e7469646164206465706f736974616461206e6f2065732061646d604482015264697469646160d81b6064820152608401610517565b6008546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd906064016020604051808303816000875af115801561070b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072f9190611bca565b90508061074e5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061197c565b336000908152600960205260408120919091556107d6846115a5565b6000858152600c60205260408120805460ff19166001179055600780549293508592909190610806908490611c31565b90915550503360008181526009602090815260409182902054825193845263ffffffff85169184019190915282820152426060830152517f998ee7ca3edf2df3955313b2583cc7f36e1ecfd3c5e2ef9c442d216b42d421d29181900360800190a150505050565b6000600080516020611ed283398151915283106108d65760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401610517565b600080516020611ed2833981519152821061093e5760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401610517565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090610980908490600401611c44565b602060405180830381865afa15801561099d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c1919061197c565b9150505b92915050565b336000908152600b602052604090205460ff1615610a2b5760405162461bcd60e51b815260206004820181905260248201527f456c2073616c646f207961206861207369646f20696e696369616c697a61646f6044820152606401610517565b6008546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a999190611995565b610aa490600a611ba4565b610aaf906032611bb3565b6008546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b158015610afc57600080fd5b505af1158015610b10573d6000803e3d6000fd5b5050336000818152600b602052604090819020805460ff1916600117905560085490516370a0823160e01b815260048101929092526001600160a01b031692506370a082319150602401602060405180830381865afa158015610b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9b919061197c565b3360009081526009602052604090205550565b6000818103610bbf57506000919050565b60035463ffffffff165b60048163ffffffff1660038110610be257610be2611c75565b01548303610bf35750600192915050565b8063ffffffff16600003610c05575060035b80610c0f81611c8b565b60035490925063ffffffff908116908316039050610bc95750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000008414610c6f5760405162461bcd60e51b815260040161051790611cab565b6000818152600a602052604090205460ff1615610cc75760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b610cd082610bae565b610cec5760405162461bcd60e51b815260040161051790611cef565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e92610d5292889283019160c0840191600401611d33565b6020604051808303816000875af1158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190611bca565b610de15760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b8152336004820152602481018790526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610e4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6f9190611bca565b905080610e8e5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa919061197c565b3360009081526009602052604081209190915560078054879290610f1f908490611da1565b909155505060408051338152602081018490529081018690527fc3ded2be7db21b1af963f267d27750e4a15f174547d88b886b9bda43e2c6fa329060600160405180910390a15050505050565b600080600080600080516020611ed28339815191524233604051602001610faf92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012060001c610fd29190611dca565b60001b9350600080516020611ed283398151915284423360405160200161101e93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b6040516020818303038152906040528051906020012060001c6110419190611dca565b60005460408051808201825287815260208101849052905163014cf2b360e51b81529295506001600160a01b039091169163299e56609161108491600401611c44565b602060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c5919061197c565b60005460408051808201825287815260208101889052905163014cf2b360e51b81529294506001600160a01b039091169163299e56609161110891600401611c44565b602060405180830381865afa158015611125573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611149919061197c565b905090919293565b6003805460009160049163ffffffff1690811061117057611170611c75565b0154905090565b6004816003811061118757600080fd5b0154905081565b7f000000000000000000000000000000000000000000000000000000000000000084146111cd5760405162461bcd60e51b815260040161051790611cab565b6000818152600a602052604090205460ff16156112255760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b61122e82610bae565b61124a5760405162461bcd60e51b815260040161051790611cef565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e926112b092889283019160c0840191600401611d33565b6020604051808303816000875af11580156112cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f39190611bca565b61133f5760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b81526001600160a01b038881166004830152602482018890529091169063a9059cbb906044016020604051808303816000875af11580156113ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cf9190611bca565b9050806113ee5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a0823190602401602060405180830381865afa158015611438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145c919061197c565b6001600160a01b0387166000908152600960205260408120919091556007805487929061148a908490611da1565b9091555050604080513381526001600160a01b03881660208201529081018690524260608201527f9ed053bb818ff08b8353cd46f78db1f0799f31c9e4458fdb425c10eccd2efc449060800160405180910390a1505050505050565b600281815481106114f657600080fd5b600091825260209091200154905081565b600d805461151490611dde565b80601f016020809104026020016040519081016040528092919081815260200182805461154090611dde565b801561158d5780601f106115625761010080835404028352916020019161158d565b820191906000526020600020905b81548152906001019060200180831161157057829003601f168201915b505050505081565b600181815481106114f657600080fd5b600354600090640100000000900463ffffffff166115e47f00000000000000000000000000000000000000000000000000000000000000006002611e12565b63ffffffff168163ffffffff16036116565760405162461bcd60e51b815260206004820152602f60248201527f4172626f6c204d65726b6c65206c6c656e6f2e204e6f2073652070756564656e60448201526e1030b3b932b3b0b9103437b530b99760891b6064820152608401610517565b6001600360048282829054906101000a900463ffffffff166116789190611e27565b92506101000a81548163ffffffff021916908363ffffffff160217905550600083905060008060005b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015611796576116e0600286611e4b565b63ffffffff166000036117415783925060028163ffffffff168154811061170957611709611c75565b906000526020600020015491508360018263ffffffff168154811061173057611730611c75565b60009182526020909120015561176b565b60018163ffffffff168154811061175a5761175a611c75565b906000526020600020015492508391505b611775838361086d565b9350611782600286611e6e565b94508061178e81611e91565b9150506116a1565b50600380546117ac9063ffffffff166001611e27565b6117b69190611e4b565b6003805463ffffffff191663ffffffff929092169182178155849160049181106117e2576117e2611c75565b015560035461180190600190640100000000900463ffffffff16611eb4565b9695505050505050565b60006020828403121561181d57600080fd5b5035919050565b6000806040838503121561183757600080fd5b50508035926020909101359150565b6000610100828403121561185957600080fd5b50919050565b600080600080610160858703121561187657600080fd5b843593506118878660208701611846565b939693955050505061012082013591610140013590565b80356001600160a01b03811681146118b557600080fd5b919050565b600080600080600061018086880312156118d357600080fd5b6118dc8661189e565b9450602086013593506118f28760408801611846565b949793965093946101408101359450610160013592915050565b60006020828403121561191e57600080fd5b6119278261189e565b9392505050565b600060208083528351808285015260005b8181101561195b5785810183015185820160400152820161193f565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561198e57600080fd5b5051919050565b6000602082840312156119a757600080fd5b815160ff8116811461192757600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b80851115611a095781600019048211156119ef576119ef6119b8565b808516156119fc57918102915b93841c93908002906119d3565b509250929050565b600181815b80851115611a09578163ffffffff04821115611a3457611a346119b8565b80851615611a4157918102915b93841c9390800290611a16565b600082611a5d575060016109c5565b81611a6a575060006109c5565b8160018114611a805760028114611a8a57611aa6565b60019150506109c5565b60ff841115611a9b57611a9b6119b8565b50506001821b6109c5565b5060208310610133831016604e8410600b8410161715611ac9575081810a6109c5565b611ad383836119ce565b8060001904821115611ae757611ae76119b8565b029392505050565b600082611afe575060016109c5565b81611b0b575060006109c5565b8160018114611a805760028103611b4d5760ff841115611b2d57611b2d6119b8565b6001841b915063ffffffff821115611b4757611b476119b8565b506109c5565b5060208310610133831016604e8410600b8410161715611b84575081810a63ffffffff811115611b7f57611b7f6119b8565b6109c5565b611b8e8383611a11565b8063ffffffff04821115611ae757611ae76119b8565b600061192760ff841683611a4e565b80820281158282048414176109c5576109c56119b8565b600060208284031215611bdc57600080fd5b8151801515811461192757600080fd5b60208082526025908201527f4c61207472616e73666572656e63696120646520746f6b656e732068612066616040820152646c6c61646f60d81b606082015260800190565b808201808211156109c5576109c56119b8565b60408101818360005b6002811015611c6c578151835260209283019290910190600101611c4d565b50505092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff821680611ca157611ca16119b8565b6000190192915050565b60208082526024908201527f4c612063616e746964616420612072657469726172206e6f2065732061646d696040820152637469646160e01b606082015260800190565b60208082526024908201527f4e6f20707565646f20656e636f6e74726172206c61207261697a206465206d65604082015263726b6c6560e01b606082015260800190565b61014081016040808784378083018660005b6002811015611d6257838284379183019190830190600101611d45565b505050808560c08501375061010082018360005b6002811015611d95578151835260209283019290910190600101611d76565b50505095945050505050565b818103818111156109c5576109c56119b8565b634e487b7160e01b600052601260045260246000fd5b600082611dd957611dd9611db4565b500690565b600181811c90821680611df257607f821691505b60208210810361185957634e487b7160e01b600052602260045260246000fd5b600063ffffffff6109c1818516828516611aef565b63ffffffff818116838216019080821115611e4457611e446119b8565b5092915050565b600063ffffffff80841680611e6257611e62611db4565b92169190910692915050565b600063ffffffff80841680611e8557611e85611db4565b92169190910492915050565b600063ffffffff808316818103611eaa57611eaa6119b8565b6001019392505050565b63ffffffff828116828216039080821115611e4457611e446119b856fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212205b9ee95936e86fb25e546403b8f3b46d12874e5fcb7668b8be16f80219a54d3064736f6c63430008140033405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5aceb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65374617274696e6720746f206275696c64206d79205a4b41544d2070726f79656374212121", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c8063ba70f757116100f9578063e829558811610097578063ef690cc011610071578063ef690cc014610473578063f178e47c14610488578063f6939c171461049b578063fc7e9c6f146104a457600080fd5b8063e829558814610426578063ec73295914610439578063ed33639f1461046057600080fd5b8063cbca47db116100d3578063cbca47db146103b8578063cd87a3b4146103db578063e3d670d7146103e3578063e5285dcc1461040357600080fd5b8063ba70f7571461038a578063c2b40ae414610392578063c6488067146103a557600080fd5b80635b26f632116101665780638bca6d16116101405780638bca6d161461031857806390eeb02b1461033f578063926d4b7f1461034f578063b8fe2a821461036257600080fd5b80635b26f632146102da5780636d9833e3146102e2578063839df945146102f557600080fd5b80632b7ac3f3116101a25780632b7ac3f31461024157806338bf282e14610268578063414a37ba146102895780634ecf518b1461029e57600080fd5b806305399e0d146101c957806317cc915c146101f95780631de26e161461022c575b600080fd5b6008546101dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61021c61020736600461180b565b600a6020526000908152604090205460ff1681565b60405190151581526020016101f0565b61023f61023a366004611824565b6104bc565b005b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b61027b610276366004611824565b61086d565b6040519081526020016101f0565b61027b600080516020611ed283398151915281565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f0565b61023f6109cb565b61021c6102f036600461180b565b610bae565b61021c61030336600461180b565b600c6020526000908152604090205460ff1681565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6003546102c59063ffffffff1681565b61023f61035d36600461185f565b610c30565b61036a610f6c565b6040805194855260208501939093529183015260608201526080016101f0565b61027b611151565b61027b6103a036600461180b565b611177565b61023f6103b33660046118ba565b61118e565b61021c6103c636600461190c565b600b6020526000908152604090205460ff1681565b6102c5600381565b61027b6103f136600461190c565b60096020526000908152604090205481565b61021c61041136600461180b565b6000908152600a602052604090205460ff1690565b61027b61043436600461180b565b6114e6565b61027b7f1d27baa01438d26e8a52f6914806cf329e273630404a9731e3035c38554973dd81565b6000546101dc906001600160a01b031681565b61047b611507565b6040516101f0919061192e565b61027b61049636600461180b565b611595565b61027b60075481565b6003546102c590640100000000900463ffffffff1681565b6000828152600c602052604090205460ff16156105205760405162461bcd60e51b815260206004820181905260248201527f456c20636f6d70726f6d69736f20796120736520686120696e7365727461646f60448201526064015b60405180910390fd5b6008546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c919061197c565b10156105ab57604051631e9acf1760e31b815260040160405180910390fd5b600860009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106229190611995565b61062d90600a611ba4565b610657907f0000000000000000000000000000000000000000000000000000000000000000611bb3565b81146106b35760405162461bcd60e51b815260206004820152602560248201527f4c612063616e7469646164206465706f736974616461206e6f2065732061646d604482015264697469646160d81b6064820152608401610517565b6008546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd906064016020604051808303816000875af115801561070b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072f9190611bca565b90508061074e5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061197c565b336000908152600960205260408120919091556107d6846115a5565b6000858152600c60205260408120805460ff19166001179055600780549293508592909190610806908490611c31565b90915550503360008181526009602090815260409182902054825193845263ffffffff85169184019190915282820152426060830152517f998ee7ca3edf2df3955313b2583cc7f36e1ecfd3c5e2ef9c442d216b42d421d29181900360800190a150505050565b6000600080516020611ed283398151915283106108d65760405162461bcd60e51b815260206004820152602160248201527f5f6c65667420646562652065737461722064656e74726f2064656c2063616d706044820152606f60f81b6064820152608401610517565b600080516020611ed2833981519152821061093e5760405162461bcd60e51b815260206004820152602260248201527f5f726967687420646562652065737461722064656e74726f2064656c2063616d604482015261706f60f01b6064820152608401610517565b60408051808201825284815260208101849052600054915163014cf2b360e51b815290916001600160a01b03169063299e566090610980908490600401611c44565b602060405180830381865afa15801561099d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c1919061197c565b9150505b92915050565b336000908152600b602052604090205460ff1615610a2b5760405162461bcd60e51b815260206004820181905260248201527f456c2073616c646f207961206861207369646f20696e696369616c697a61646f6044820152606401610517565b6008546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a999190611995565b610aa490600a611ba4565b610aaf906032611bb3565b6008546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b158015610afc57600080fd5b505af1158015610b10573d6000803e3d6000fd5b5050336000818152600b602052604090819020805460ff1916600117905560085490516370a0823160e01b815260048101929092526001600160a01b031692506370a082319150602401602060405180830381865afa158015610b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9b919061197c565b3360009081526009602052604090205550565b6000818103610bbf57506000919050565b60035463ffffffff165b60048163ffffffff1660038110610be257610be2611c75565b01548303610bf35750600192915050565b8063ffffffff16600003610c05575060035b80610c0f81611c8b565b60035490925063ffffffff908116908316039050610bc95750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000008414610c6f5760405162461bcd60e51b815260040161051790611cab565b6000818152600a602052604090205460ff1615610cc75760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b610cd082610bae565b610cec5760405162461bcd60e51b815260040161051790611cef565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e92610d5292889283019160c0840191600401611d33565b6020604051808303816000875af1158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190611bca565b610de15760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b8152336004820152602481018790526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610e4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6f9190611bca565b905080610e8e5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa919061197c565b3360009081526009602052604081209190915560078054879290610f1f908490611da1565b909155505060408051338152602081018490529081018690527fc3ded2be7db21b1af963f267d27750e4a15f174547d88b886b9bda43e2c6fa329060600160405180910390a15050505050565b600080600080600080516020611ed28339815191524233604051602001610faf92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012060001c610fd29190611dca565b60001b9350600080516020611ed283398151915284423360405160200161101e93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b6040516020818303038152906040528051906020012060001c6110419190611dca565b60005460408051808201825287815260208101849052905163014cf2b360e51b81529295506001600160a01b039091169163299e56609161108491600401611c44565b602060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c5919061197c565b60005460408051808201825287815260208101889052905163014cf2b360e51b81529294506001600160a01b039091169163299e56609161110891600401611c44565b602060405180830381865afa158015611125573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611149919061197c565b905090919293565b6003805460009160049163ffffffff1690811061117057611170611c75565b0154905090565b6004816003811061118757600080fd5b0154905081565b7f000000000000000000000000000000000000000000000000000000000000000084146111cd5760405162461bcd60e51b815260040161051790611cab565b6000818152600a602052604090205460ff16156112255760405162461bcd60e51b81526020600482015260166024820152754c61206e6f746120796120667565206761737461646160501b6044820152606401610517565b61122e82610bae565b61124a5760405162461bcd60e51b815260040161051790611cef565b604080518082018252838152602081018390528151637ae4eb4f60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263f5c9d69e926112b092889283019160c0840191600401611d33565b6020604051808303816000875af11580156112cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f39190611bca565b61133f5760405162461bcd60e51b815260206004820152601d60248201527f50727565626120706172612072657469726172206e6f2076616c6964610000006044820152606401610517565b6000818152600a6020526040808220805460ff19166001179055600854905163a9059cbb60e01b81526001600160a01b038881166004830152602482018890529091169063a9059cbb906044016020604051808303816000875af11580156113ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cf9190611bca565b9050806113ee5760405162461bcd60e51b815260040161051790611bec565b6008546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a0823190602401602060405180830381865afa158015611438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145c919061197c565b6001600160a01b0387166000908152600960205260408120919091556007805487929061148a908490611da1565b9091555050604080513381526001600160a01b03881660208201529081018690524260608201527f9ed053bb818ff08b8353cd46f78db1f0799f31c9e4458fdb425c10eccd2efc449060800160405180910390a1505050505050565b600281815481106114f657600080fd5b600091825260209091200154905081565b600d805461151490611dde565b80601f016020809104026020016040519081016040528092919081815260200182805461154090611dde565b801561158d5780601f106115625761010080835404028352916020019161158d565b820191906000526020600020905b81548152906001019060200180831161157057829003601f168201915b505050505081565b600181815481106114f657600080fd5b600354600090640100000000900463ffffffff166115e47f00000000000000000000000000000000000000000000000000000000000000006002611e12565b63ffffffff168163ffffffff16036116565760405162461bcd60e51b815260206004820152602f60248201527f4172626f6c204d65726b6c65206c6c656e6f2e204e6f2073652070756564656e60448201526e1030b3b932b3b0b9103437b530b99760891b6064820152608401610517565b6001600360048282829054906101000a900463ffffffff166116789190611e27565b92506101000a81548163ffffffff021916908363ffffffff160217905550600083905060008060005b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015611796576116e0600286611e4b565b63ffffffff166000036117415783925060028163ffffffff168154811061170957611709611c75565b906000526020600020015491508360018263ffffffff168154811061173057611730611c75565b60009182526020909120015561176b565b60018163ffffffff168154811061175a5761175a611c75565b906000526020600020015492508391505b611775838361086d565b9350611782600286611e6e565b94508061178e81611e91565b9150506116a1565b50600380546117ac9063ffffffff166001611e27565b6117b69190611e4b565b6003805463ffffffff191663ffffffff929092169182178155849160049181106117e2576117e2611c75565b015560035461180190600190640100000000900463ffffffff16611eb4565b9695505050505050565b60006020828403121561181d57600080fd5b5035919050565b6000806040838503121561183757600080fd5b50508035926020909101359150565b6000610100828403121561185957600080fd5b50919050565b600080600080610160858703121561187657600080fd5b843593506118878660208701611846565b939693955050505061012082013591610140013590565b80356001600160a01b03811681146118b557600080fd5b919050565b600080600080600061018086880312156118d357600080fd5b6118dc8661189e565b9450602086013593506118f28760408801611846565b949793965093946101408101359450610160013592915050565b60006020828403121561191e57600080fd5b6119278261189e565b9392505050565b600060208083528351808285015260005b8181101561195b5785810183015185820160400152820161193f565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561198e57600080fd5b5051919050565b6000602082840312156119a757600080fd5b815160ff8116811461192757600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b80851115611a095781600019048211156119ef576119ef6119b8565b808516156119fc57918102915b93841c93908002906119d3565b509250929050565b600181815b80851115611a09578163ffffffff04821115611a3457611a346119b8565b80851615611a4157918102915b93841c9390800290611a16565b600082611a5d575060016109c5565b81611a6a575060006109c5565b8160018114611a805760028114611a8a57611aa6565b60019150506109c5565b60ff841115611a9b57611a9b6119b8565b50506001821b6109c5565b5060208310610133831016604e8410600b8410161715611ac9575081810a6109c5565b611ad383836119ce565b8060001904821115611ae757611ae76119b8565b029392505050565b600082611afe575060016109c5565b81611b0b575060006109c5565b8160018114611a805760028103611b4d5760ff841115611b2d57611b2d6119b8565b6001841b915063ffffffff821115611b4757611b476119b8565b506109c5565b5060208310610133831016604e8410600b8410161715611b84575081810a63ffffffff811115611b7f57611b7f6119b8565b6109c5565b611b8e8383611a11565b8063ffffffff04821115611ae757611ae76119b8565b600061192760ff841683611a4e565b80820281158282048414176109c5576109c56119b8565b600060208284031215611bdc57600080fd5b8151801515811461192757600080fd5b60208082526025908201527f4c61207472616e73666572656e63696120646520746f6b656e732068612066616040820152646c6c61646f60d81b606082015260800190565b808201808211156109c5576109c56119b8565b60408101818360005b6002811015611c6c578151835260209283019290910190600101611c4d565b50505092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff821680611ca157611ca16119b8565b6000190192915050565b60208082526024908201527f4c612063616e746964616420612072657469726172206e6f2065732061646d696040820152637469646160e01b606082015260800190565b60208082526024908201527f4e6f20707565646f20656e636f6e74726172206c61207261697a206465206d65604082015263726b6c6560e01b606082015260800190565b61014081016040808784378083018660005b6002811015611d6257838284379183019190830190600101611d45565b505050808560c08501375061010082018360005b6002811015611d95578151835260209283019290910190600101611d76565b50505095945050505050565b818103818111156109c5576109c56119b8565b634e487b7160e01b600052601260045260246000fd5b600082611dd957611dd9611db4565b500690565b600181811c90821680611df257607f821691505b60208210810361185957634e487b7160e01b600052602260045260246000fd5b600063ffffffff6109c1818516828516611aef565b63ffffffff818116838216019080821115611e4457611e446119b8565b5092915050565b600063ffffffff80841680611e6257611e62611db4565b92169190910692915050565b600063ffffffff80841680611e8557611e85611db4565b92169190910492915050565b600063ffffffff808316818103611eaa57611eaa6119b8565b6001019392505050565b63ffffffff828116828216039080821115611e4457611e446119b856fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212205b9ee95936e86fb25e546403b8f3b46d12874e5fcb7668b8be16f80219a54d3064736f6c63430008140033", "devdoc": { "kind": "dev", "methods": {}, @@ -678,15 +678,15 @@ "storageLayout": { "storage": [ { - "astId": 1681, + "astId": 1682, "contract": "contracts/ATM.sol:ATM", "label": "hasher", "offset": 0, "slot": "0", - "type": "t_contract(Hasher)1672" + "type": "t_contract(Hasher)1673" }, { - "astId": 1686, + "astId": 1687, "contract": "contracts/ATM.sol:ATM", "label": "filledSubtrees", "offset": 0, @@ -694,7 +694,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 1689, + "astId": 1690, "contract": "contracts/ATM.sol:ATM", "label": "zeros", "offset": 0, @@ -702,7 +702,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 1692, + "astId": 1693, "contract": "contracts/ATM.sol:ATM", "label": "currentRootIndex", "offset": 0, @@ -710,7 +710,7 @@ "type": "t_uint32" }, { - "astId": 1695, + "astId": 1696, "contract": "contracts/ATM.sol:ATM", "label": "nextIndex", "offset": 4, @@ -718,7 +718,7 @@ "type": "t_uint32" }, { - "astId": 1702, + "astId": 1703, "contract": "contracts/ATM.sol:ATM", "label": "roots", "offset": 0, @@ -739,7 +739,7 @@ "label": "zkatmToken", "offset": 0, "slot": "8", - "type": "t_contract(ZKATM_Token)2126" + "type": "t_contract(ZKATM_Token)2127" }, { "astId": 1144, @@ -810,12 +810,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(Hasher)1672": { + "t_contract(Hasher)1673": { "encoding": "inplace", "label": "contract Hasher", "numberOfBytes": "20" }, - "t_contract(ZKATM_Token)2126": { + "t_contract(ZKATM_Token)2127": { "encoding": "inplace", "label": "contract ZKATM_Token", "numberOfBytes": "20" diff --git a/packages/hardhat/deployments/scrollSepolia/ZKATM_Token.json b/packages/hardhat/deployments/scrollSepolia/ZKATM_Token.json index 11338f3..e6f1481 100644 --- a/packages/hardhat/deployments/scrollSepolia/ZKATM_Token.json +++ b/packages/hardhat/deployments/scrollSepolia/ZKATM_Token.json @@ -1,5 +1,5 @@ { - "address": "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9", + "address": "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9", "abi": [ { "inputs": [ @@ -515,55 +515,55 @@ "type": "function" } ], - "transactionHash": "0x12fddffcb8e68da624b21bb5bead2004ac853f0b3025764637da6de8c5ed0dd7", + "transactionHash": "0x984adea86081cb1a5eee8a9121b249d986e98c981edf199b59f5576b70a61c86", "receipt": { "to": null, - "from": "0x5Fdc37574A0FE07fc0d47E6A749242DaBB1B09eE", - "contractAddress": "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9", + "from": "0x1E89B43Cfe9E3F391bc8f0f8CE8d29036C26C63D", + "contractAddress": "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9", "transactionIndex": 1, "gasUsed": "852894", - "logsBloom": "0x00200000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000001000000000000000000000000000000000000020000000000201000000800000000000000000000000010000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000002000000000000000000000000000000000000000000000000000020000000002000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd1afef670cc41dade37ab8ac563c687a18530c4c8d04eade7224e7c513236b04", - "transactionHash": "0x12fddffcb8e68da624b21bb5bead2004ac853f0b3025764637da6de8c5ed0dd7", + "logsBloom": "0x08000000000000000000004000000000000000000000000000800000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000001000000000000000000000000000000000000020000000000000000000800000000000000000800200010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000800000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x258ce65617e1b6ad9e626d829d0eafe3b11ac08c33af597c13c423535dd35bc5", + "transactionHash": "0x984adea86081cb1a5eee8a9121b249d986e98c981edf199b59f5576b70a61c86", "logs": [ { "transactionIndex": 1, - "blockNumber": 5546001, - "transactionHash": "0x12fddffcb8e68da624b21bb5bead2004ac853f0b3025764637da6de8c5ed0dd7", - "address": "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9", + "blockNumber": 5599758, + "transactionHash": "0x984adea86081cb1a5eee8a9121b249d986e98c981edf199b59f5576b70a61c86", + "address": "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000005fdc37574a0fe07fc0d47e6a749242dabb1b09ee" + "0x0000000000000000000000001e89b43cfe9e3f391bc8f0f8ce8d29036c26c63d" ], "data": "0x", "logIndex": 0, - "blockHash": "0xd1afef670cc41dade37ab8ac563c687a18530c4c8d04eade7224e7c513236b04" + "blockHash": "0x258ce65617e1b6ad9e626d829d0eafe3b11ac08c33af597c13c423535dd35bc5" }, { "transactionIndex": 1, - "blockNumber": 5546001, - "transactionHash": "0x12fddffcb8e68da624b21bb5bead2004ac853f0b3025764637da6de8c5ed0dd7", - "address": "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9", + "blockNumber": 5599758, + "transactionHash": "0x984adea86081cb1a5eee8a9121b249d986e98c981edf199b59f5576b70a61c86", + "address": "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000005fdc37574a0fe07fc0d47e6a749242dabb1b09ee" + "0x0000000000000000000000001e89b43cfe9e3f391bc8f0f8ce8d29036c26c63d" ], "data": "0x00000000000000000000000000000000000000000000d3c21bcecceda1000000", "logIndex": 1, - "blockHash": "0xd1afef670cc41dade37ab8ac563c687a18530c4c8d04eade7224e7c513236b04" + "blockHash": "0x258ce65617e1b6ad9e626d829d0eafe3b11ac08c33af597c13c423535dd35bc5" } ], - "blockNumber": 5546001, + "blockNumber": 5599758, "cumulativeGasUsed": "873894", "status": 1, "byzantium": true }, "args": [ - "0x5Fdc37574A0FE07fc0d47E6A749242DaBB1B09eE" + "0x1E89B43Cfe9E3F391bc8f0f8CE8d29036C26C63D" ], - "numDeployments": 4, + "numDeployments": 5, "solcInputHash": "d93222a9a90638f996fd3788b0f84fc4", "metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EnforcedPause\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExpectedPause\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"atmAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"greeting\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_atm\",\"type\":\"address\"}],\"name\":\"updateATMAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"ERC20InsufficientAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\",\"params\":{\"allowance\":\"Amount of tokens a `spender` is allowed to operate with.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC20InsufficientBalance(address,uint256,uint256)\":[{\"details\":\"Indicates an error related to the current `balance` of a `sender`. Used in transfers.\",\"params\":{\"balance\":\"Current balance for the interacting account.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidApprover(address)\":[{\"details\":\"Indicates a failure with the `approver` of a token to be approved. Used in approvals.\",\"params\":{\"approver\":\"Address initiating an approval operation.\"}}],\"ERC20InvalidReceiver(address)\":[{\"details\":\"Indicates a failure with the token `receiver`. Used in transfers.\",\"params\":{\"receiver\":\"Address to which tokens are being transferred.\"}}],\"ERC20InvalidSender(address)\":[{\"details\":\"Indicates a failure with the token `sender`. Used in transfers.\",\"params\":{\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidSpender(address)\":[{\"details\":\"Indicates a failure with the `spender` to be approved. Used in approvals.\",\"params\":{\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"EnforcedPause()\":[{\"details\":\"The operation failed because the contract is paused.\"}],\"ExpectedPause()\":[{\"details\":\"The operation failed because the contract is not paused.\"}],\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}]},\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ZKATM_Token.sol\":\"ZKATM_Token\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../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 * The initial owner is set to the address provided by the deployer. This can\\n * 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 /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\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 if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\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\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"./extensions/IERC20Metadata.sol\\\";\\nimport {Context} from \\\"../../utils/Context.sol\\\";\\nimport {IERC20Errors} from \\\"../../interfaces/draft-IERC6093.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n */\\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\\n mapping(address account => uint256) private _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n _totalSupply += value;\\n } else {\\n uint256 fromBalance = _balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n _balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n _totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n _balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n _allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20} from \\\"../ERC20.sol\\\";\\nimport {Pausable} from \\\"../../../utils/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract pause mechanism of the contract unreachable, and thus unusable.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_update}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {\\n super._update(from, to, value);\\n }\\n}\\n\",\"keccak256\":\"0xb18c53aecf95e53339972e3d496a56c42e6b60a03a49ce8e6a37d3bd9d5d0a67\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\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 function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n bool private _paused;\\n\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n /**\\n * @dev The operation failed because the contract is paused.\\n */\\n error EnforcedPause();\\n\\n /**\\n * @dev The operation failed because the contract is not paused.\\n */\\n error ExpectedPause();\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor() {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n if (paused()) {\\n revert EnforcedPause();\\n }\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n if (!paused()) {\\n revert ExpectedPause();\\n }\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xb2e5f50762c27fb4b123e3619c3c02bdcba5e515309382e5bfb6f7d6486510bd\",\"license\":\"MIT\"},\"contracts/ZKATM_Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n// Compatible with OpenZeppelin Contracts ^5.0.0\\r\\npragma solidity >=0.8.20 <0.9.0;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\n\\r\\ncontract ZKATM_Token is ERC20, ERC20Pausable, Ownable {\\r\\n string public greeting = \\\"Deploy token ZKATM\\\";\\r\\n address public atmAddress;\\r\\n\\r\\n constructor(address initialOwner)\\r\\n ERC20(\\\"ZKATM_Token\\\", \\\"ZKATM\\\")\\r\\n Ownable(initialOwner)\\r\\n {\\r\\n _mint(msg.sender, 1000000 * 10 ** decimals());\\r\\n }\\r\\n \\r\\n function updateATMAddress(address _atm) external onlyOwner {\\r\\n atmAddress = _atm;\\r\\n }\\r\\n\\r\\n function pause() public onlyOwner {\\r\\n _pause();\\r\\n }\\r\\n\\r\\n function unpause() public onlyOwner {\\r\\n _unpause();\\r\\n }\\r\\n\\r\\n function mint(address to, uint256 amount) public onlyATM {\\r\\n _mint(to, amount);\\r\\n }\\r\\n\\r\\n // The following functions are overrides required by Solidity.\\r\\n\\r\\n function _update(address from, address to, uint256 value)\\r\\n internal\\r\\n override(ERC20, ERC20Pausable)\\r\\n {\\r\\n super._update(from, to, value);\\r\\n }\\r\\n\\r\\n modifier onlyATM(){\\r\\n require(msg.sender == atmAddress, \\\"only_atm\\\");\\r\\n _;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xbc0e472adf7a86c9d43874315ec8e6fa61d45e8ab743cb404a6a5f20bb017dd9\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x60c060405260126080908152714465706c6f7920746f6b656e205a4b41544d60701b60a052600690620000339082620003fe565b503480156200004157600080fd5b50604051620011e2380380620011e28339810160408190526200006491620004ca565b806040518060400160405280600b81526020016a2d25a0aa26afaa37b5b2b760a91b815250604051806040016040528060058152602001645a4b41544d60d81b8152508160039081620000b89190620003fe565b506004620000c78282620003fe565b50506005805460ff19169055506001600160a01b0381166200010457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200010f816200013f565b506200013833620001236012600a62000611565b6200013290620f424062000622565b62000199565b5062000652565b600580546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216620001c55760405163ec442f0560e01b815260006004820152602401620000fb565b620001d360008383620001d7565b5050565b620001e4838383620001e9565b505050565b620001f362000200565b620001e483838362000227565b60055460ff1615620002255760405163d93c066560e01b815260040160405180910390fd5b565b6001600160a01b038316620002565780600260008282546200024a91906200063c565b90915550620002ca9050565b6001600160a01b03831660009081526020819052604090205481811015620002ab5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401620000fb565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216620002e85760028054829003905562000307565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200034d91815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200038557607f821691505b602082108103620003a657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001e457600081815260208120601f850160051c81016020861015620003d55750805b601f850160051c820191505b81811015620003f657828155600101620003e1565b505050505050565b81516001600160401b038111156200041a576200041a6200035a565b62000432816200042b845462000370565b84620003ac565b602080601f8311600181146200046a5760008415620004515750858301515b600019600386901b1c1916600185901b178555620003f6565b600085815260208120601f198616915b828110156200049b578886015182559484019460019091019084016200047a565b5085821015620004ba5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215620004dd57600080fd5b81516001600160a01b0381168114620004f557600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000553578160001904821115620005375762000537620004fc565b808516156200054557918102915b93841c939080029062000517565b509250929050565b6000826200056c575060016200060b565b816200057b575060006200060b565b81600181146200059457600281146200059f57620005bf565b60019150506200060b565b60ff841115620005b357620005b3620004fc565b50506001821b6200060b565b5060208310610133831016604e8410600b8410161715620005e4575081810a6200060b565b620005f0838362000512565b8060001904821115620006075762000607620004fc565b0290505b92915050565b6000620004f560ff8416836200055b565b80820281158282048414176200060b576200060b620004fc565b808201808211156200060b576200060b620004fc565b610b8080620006626000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806370a08231116100ad578063a9059cbb11610071578063a9059cbb14610241578063cb7abc5214610254578063dd62ed3e14610267578063ef690cc0146102a0578063f2fde38b146102a857600080fd5b806370a08231146101d6578063715018a6146101ff5780638456cb59146102075780638da5cb5b1461020f57806395d89b411461023957600080fd5b8063313ce567116100f4578063313ce5671461018c5780633f4ba83a1461019b57806340c10f19146101a55780635c975abb146101b8578063667380ce146101c357600080fd5b806306fdde0314610126578063095ea7b31461014457806318160ddd1461016757806323b872dd14610179575b600080fd5b61012e6102bb565b60405161013b91906109ca565b60405180910390f35b610157610152366004610a34565b61034d565b604051901515815260200161013b565b6002545b60405190815260200161013b565b610157610187366004610a5e565b610367565b6040516012815260200161013b565b6101a361038b565b005b6101a36101b3366004610a34565b61039d565b60055460ff16610157565b6101a36101d1366004610a9a565b6103f5565b61016b6101e4366004610a9a565b6001600160a01b031660009081526020819052604090205490565b6101a361041f565b6101a3610431565b60055461010090046001600160a01b03165b6040516001600160a01b03909116815260200161013b565b61012e610441565b61015761024f366004610a34565b610450565b600754610221906001600160a01b031681565b61016b610275366004610abc565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61012e61045e565b6101a36102b6366004610a9a565b6104ec565b6060600380546102ca90610aef565b80601f01602080910402602001604051908101604052809291908181526020018280546102f690610aef565b80156103435780601f1061031857610100808354040283529160200191610343565b820191906000526020600020905b81548152906001019060200180831161032657829003601f168201915b5050505050905090565b60003361035b81858561052a565b60019150505b92915050565b60003361037585828561053c565b6103808585856105ba565b506001949350505050565b610393610619565b61039b61064c565b565b6007546001600160a01b031633146103e75760405162461bcd60e51b81526020600482015260086024820152676f6e6c795f61746d60c01b60448201526064015b60405180910390fd5b6103f1828261069e565b5050565b6103fd610619565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b610427610619565b61039b60006106d4565b610439610619565b61039b61072e565b6060600480546102ca90610aef565b60003361035b8185856105ba565b6006805461046b90610aef565b80601f016020809104026020016040519081016040528092919081815260200182805461049790610aef565b80156104e45780601f106104b9576101008083540402835291602001916104e4565b820191906000526020600020905b8154815290600101906020018083116104c757829003601f168201915b505050505081565b6104f4610619565b6001600160a01b03811661051e57604051631e4fbdf760e01b8152600060048201526024016103de565b610527816106d4565b50565b610537838383600161076b565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105b457818110156105a557604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016103de565b6105b48484848403600061076b565b50505050565b6001600160a01b0383166105e457604051634b637e8f60e11b8152600060048201526024016103de565b6001600160a01b03821661060e5760405163ec442f0560e01b8152600060048201526024016103de565b610537838383610840565b6005546001600160a01b0361010090910416331461039b5760405163118cdaa760e01b81523360048201526024016103de565b61065461084b565b6005805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166106c85760405163ec442f0560e01b8152600060048201526024016103de565b6103f160008383610840565b600580546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61073661086e565b6005805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586106813390565b6001600160a01b0384166107955760405163e602df0560e01b8152600060048201526024016103de565b6001600160a01b0383166107bf57604051634a1406b160e11b8152600060048201526024016103de565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156105b457826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161083291815260200190565b60405180910390a350505050565b610537838383610892565b60055460ff1661039b57604051638dfc202b60e01b815260040160405180910390fd5b60055460ff161561039b5760405163d93c066560e01b815260040160405180910390fd5b61089a61086e565b6105378383836001600160a01b0383166108cb5780600260008282546108c09190610b29565b9091555061093d9050565b6001600160a01b0383166000908152602081905260409020548181101561091e5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016103de565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661095957600280548290039055610978565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516109bd91815260200190565b60405180910390a3505050565b600060208083528351808285015260005b818110156109f7578581018301518582016040015282016109db565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a2f57600080fd5b919050565b60008060408385031215610a4757600080fd5b610a5083610a18565b946020939093013593505050565b600080600060608486031215610a7357600080fd5b610a7c84610a18565b9250610a8a60208501610a18565b9150604084013590509250925092565b600060208284031215610aac57600080fd5b610ab582610a18565b9392505050565b60008060408385031215610acf57600080fd5b610ad883610a18565b9150610ae660208401610a18565b90509250929050565b600181811c90821680610b0357607f821691505b602082108103610b2357634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561036157634e487b7160e01b600052601160045260246000fdfea2646970667358221220abc7a38b7c87952ec7efe07168b209bdff3288c6915a212b54b608500b1950d564736f6c63430008140033", diff --git a/packages/hardhat/deployments/scrollSepolia/solcInputs/43db542302d86338e39f94e2c1de71f6.json b/packages/hardhat/deployments/scrollSepolia/solcInputs/43db542302d86338e39f94e2c1de71f6.json new file mode 100644 index 0000000..4a9b304 --- /dev/null +++ b/packages/hardhat/deployments/scrollSepolia/solcInputs/43db542302d86338e39f94e2c1de71f6.json @@ -0,0 +1,66 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../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 * The initial owner is set to the address provided by the deployer. This can\n * 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 /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\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 if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n * ```\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ERC20} from \"../ERC20.sol\";\nimport {Pausable} from \"../../../utils/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract pause mechanism of the contract unreachable, and thus unusable.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_update}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {\n super._update(from, to, value);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\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 function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n bool private _paused;\n\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n /**\n * @dev The operation failed because the contract is paused.\n */\n error EnforcedPause();\n\n /**\n * @dev The operation failed because the contract is not paused.\n */\n error ExpectedPause();\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n if (paused()) {\n revert EnforcedPause();\n }\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n if (!paused()) {\n revert ExpectedPause();\n }\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "contracts/ATM.sol": { + "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.8.0 <0.9.0;\r\nimport \"./MerkleTree.sol\";\r\nimport \"./ZKATM_Token.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\"; // Importar interfaz del token ERC20\r\n\r\nstruct Proof {\r\n uint256[2] a;\r\n uint256[2][2] b;\r\n uint256[2] c;\r\n}\r\n\r\ninterface IVerifier {\r\n function verifyProof(\r\n\t\tuint256[2] calldata a, \r\n \t\tuint256[2][2] calldata b,\r\n uint256[2] calldata c,\r\n\t\tuint256[2] memory _input\r\n\t) external returns (bool);\r\n}\r\n\r\ncontract ATM is MerkleTree {\r\n\tuint256 public immutable denomination;\r\n\tIVerifier public immutable verifier;\r\n\tuint256 public balanceTotalATM;\r\n\tZKATM_Token public zkatmToken; // referencia del token ZKATM\r\n\tmapping (address _account => uint256 _balance) public balance;\r\n\tmapping (bytes32 => bool) public nullifierHashes;\r\n\tmapping (address _account => bool) public initialized;\r\n\t// almacenar compromisos para evitar depósitos accidentales con el mismo compromiso.\r\n\tmapping(bytes32 => bool) public commitments; \t\t\t\t\t\t \r\n\tstring public greeting = \"Starting to build my ZKATM proyect!!!\";\r\n\t// _verifier --> la dirección del contrato verificador para este SNARK\r\n\t// _hasher --> la dirección del contrato hash poseidon \r\n\t// _denomination --> cantidad a transferir por cada deposito\r\n // _merkleTreeHeight --> la altura del árbol Merkle de los depósitos\r\n\t// Hasher address (Poseidon 1 args): 0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41\r\n\t// Verifier address: 0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9\r\n\t\r\n\tconstructor(\r\n \tIVerifier _verifier,\r\n\t\taddress _hasher,\r\n\t\tuint256 _denomination,\r\n \tuint32 _merkleTreeHeight,\r\n\t\tZKATM_Token _zkatmToken // Añade este parámetro para el token ZKATM\r\n \t)MerkleTree(_merkleTreeHeight, _hasher){\r\n \tverifier = _verifier;\r\n\t\thasher = Hasher(_hasher);\r\n\t\tdenomination = _denomination;\r\n\t\tzkatmToken = _zkatmToken; // Inicializa la referencia del token ZKATM\r\n \t}\r\n\r\n\tfunction initializeBalance() external {\r\n require(!initialized[msg.sender], \"El saldo ya ha sido inicializado\");\r\n\t\t// Transferir 50 tokens ZKATM al usuario que llama la función\r\n uint256 tokenAmount = 50 * (10 ** zkatmToken.decimals()); // Ajuste según los decimales del token\r\n zkatmToken.mint(msg.sender, tokenAmount);\r\n\t\tinitialized[msg.sender] = true;\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n }\r\n\r\n event Deposit (address from, uint32 leafIndex, uint256 value, uint256 timestamp);\r\n event Transfer (address from, address to, uint256 value, uint256 timestamp);\r\n event Withdraw (address to, bytes32 _nullifierHash, uint256 value);\r\n\t\r\n error InsufficientBalance();\r\n\r\n\tfunction generateCommitment() public view returns (\r\n\t\tbytes32 nullifier, \r\n\t\tbytes32 secret,\r\n\t \tbytes32 commitment, \r\n\t\tbytes32 nullifierHash\r\n\t\t) {\r\n\t\t// Puedes ajustar cómo generas el nullifier\r\n nullifier = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \r\n\t\t// Puedes ajustar cómo generas el secret\r\n secret = bytes32(uint256(keccak256(abi.encodePacked(nullifier, block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \r\n\t\tcommitment = hasher.poseidon([nullifier, secret]);\r\n nullifierHash = hasher.poseidon([nullifier, nullifier]);\r\n }\r\n\r\n\t// commitment el compromiso de nota, que es poseidonhash(anulador + secreto)\r\n function deposit(bytes32 commitment, uint256 _amount) public {\r\n\t\trequire(!commitments[commitment], \"El compromiso ya se ha insertado\");\r\n\t\tif(balance[msg.sender] < _amount) revert InsufficientBalance();\r\n\t\trequire(_amount == (denomination * (10 ** zkatmToken.decimals())), \"La cantidad depositada no es admitida\");\r\n\t\t\r\n\t\t// Transfiere los tokens desde el usuario que llama a la función hacia este contrato\r\n \tbool transferSuccess = zkatmToken.transferFrom(msg.sender, address(this), _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n\t\tuint32 insertedIndex = _insert(commitment);\r\n\t\tcommitments[commitment] = true;\r\n\t\tbalanceTotalATM += _amount;\r\n\t\temit Deposit (msg.sender, insertedIndex, balance[msg.sender], block.timestamp);\r\n\t}\r\n\r\n\t// _proof --> son datos de la prueba zkSNARK y la entrada es una matriz de entradas públicas del circuito.\r\n\t// _input --> un array del cicuito con las siguientes entradas publicas:\r\n // - raíz merkle de todos los depósitos en el contrato\r\n // - hash de anulador de depósito único para evitar gastos dobles\r\n function withdraw(uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\r\n\t\trequire(_amount == denomination, \"La cantidad a retirar no es admitida\");\r\n\t\trequire(!nullifierHashes[_nullifierHash], \"La nota ya fue gastada\");\r\n\t\trequire(isKnownRoot(_root), \"No puedo encontrar la raiz de merkle\"); //Asegúrate de usar uno de los ultimos 3 reciente\r\n\t\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \"Prueba para retirar no valida\");\r\n\t\tnullifierHashes[_nullifierHash] = true;\r\n\r\n\t\t// Transfiere los tokens desde el contrato al usuario que llama a la función\r\n \tbool transferSuccess = zkatmToken.transfer(msg.sender, _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\t\t\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n\t\tbalanceTotalATM -= _amount;\r\n\t\temit Withdraw (msg.sender, _nullifierHash, _amount);\r\n\t}\r\n\r\n function transfer(address _receiver, uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\r\n\t\trequire(_amount == denomination, \"La cantidad a retirar no es admitida\");\r\n\t\trequire(!nullifierHashes[_nullifierHash], \"La nota ya fue gastada\");\r\n\t\trequire(isKnownRoot(_root), \"No puedo encontrar la raiz de merkle\"); //Asegúrate de usar uno de los ultimos 3 reciente\r\n\t\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \"Prueba para retirar no valida\");\r\n\t\tnullifierHashes[_nullifierHash] = true;\r\n\r\n\t\t// Transfiere los tokens desde el contrato al usuario que llama a la función\r\n \tbool transferSuccess = zkatmToken.transfer(_receiver, _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\t\tbalance[_receiver] = zkatmToken.balanceOf(_receiver);\r\n\t\tbalanceTotalATM -= _amount;\r\n\t\temit Transfer (msg.sender, _receiver, _amount, block.timestamp);\r\n\t}\r\n\t function isSpent(bytes32 _nullifierHash) public view returns (bool) {\r\n return nullifierHashes[_nullifierHash];\r\n } \r\n}\r\n" + }, + "contracts/MerkleTree.sol": { + "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\ninterface Hasher {\r\n function poseidon(bytes32[2] calldata leftRight) external pure returns (bytes32);\r\n}\r\n\r\ncontract MerkleTree {\r\n uint256 public constant FIELD_SIZE =\r\n 21888242871839275222246405745257275088548364400416034343698204186575808495617; // orden (cardinalidad) de la curva\r\n uint256 public constant ZERO_VALUE =\r\n 13187267684982673088682801604133345722716467932170606900401783776316647633885; // = keccak256(\"MiATM\") % FIELD_SIZE\r\n\r\n Hasher public hasher;\r\n uint32 public immutable levels;\r\n\r\n // las siguientes variables se hacen públicas para facilitar las pruebas y\r\n // se que no se debe acceder a ellas mediante código normal\r\n bytes32[] public filledSubtrees; // arreglo con roots del subarbol a la izquierda de una hoja (de tamaño _levels)\r\n bytes32[] public zeros; // arreglo con roots del subarbol a la derecha de una hoja (de tamaño _levels)\r\n uint32 public currentRootIndex = 0;\r\n uint32 public nextIndex = 0;\r\n uint32 public constant ROOT_HISTORY_SIZE = 3; // tiene que ser menor que 2**levels (cada nueva hoja nueva raíz)\r\n bytes32[ROOT_HISTORY_SIZE] public roots;\r\n\r\n constructor(uint32 _levels, address _hasher) {\r\n require(_levels > 0, \"_levels debe ser mayor que cero\");\r\n require(_levels < 6, \"_levels debe ser menor que 6\");\r\n levels = _levels;\r\n hasher = Hasher(_hasher);\r\n \r\n bytes32 currentZero = bytes32(ZERO_VALUE);\r\n zeros.push(currentZero);\r\n filledSubtrees.push(currentZero);\r\n\r\n // Obteniendo la primera raiz para todas las hojas vacias\r\n for (uint32 i = 1; i < _levels; i++) {\r\n currentZero = hashLeftRight(currentZero, currentZero);\r\n zeros.push(currentZero); \r\n filledSubtrees.push(currentZero);\r\n }\r\n\r\n roots[0] = hashLeftRight(currentZero, currentZero); // comentar raiz predeterminada siempre es la misma dependiedo del nivel\r\n }\r\n\r\n // Hasheando 2 hojas del árbol, devuelve poseidon(leftright)\r\n function hashLeftRight(bytes32 _left, bytes32 _right) public view returns (bytes32) {\r\n require(uint256(_left) < FIELD_SIZE, \"_left debe estar dentro del campo\" );\r\n require(uint256(_right) < FIELD_SIZE, \"_right debe estar dentro del campo\" );\r\n bytes32[2] memory leftright = [_left, _right];\r\n return hasher.poseidon(leftright);\r\n }\r\n\r\n function _insert(bytes32 _leaf) internal returns (uint32 index) {\r\n uint32 currentIndex = nextIndex;\r\n require(currentIndex != uint32(2)**levels, \"Arbol Merkle lleno. No se pueden agregar hojas.\");\r\n nextIndex += 1;\r\n bytes32 currentLevelHash = _leaf;\r\n bytes32 left;\r\n bytes32 right;\r\n\r\n for (uint32 i = 0; i < levels; i++) {\r\n if (currentIndex % 2 == 0) {\r\n left = currentLevelHash;\r\n right = zeros[i];\r\n \r\n filledSubtrees[i] = currentLevelHash;\r\n } else {\r\n left = filledSubtrees[i];\r\n right = currentLevelHash;\r\n }\r\n\r\n currentLevelHash = hashLeftRight(left, right);\r\n\r\n currentIndex /= 2;\r\n }\r\n\r\n currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\r\n roots[currentRootIndex] = currentLevelHash;\r\n return nextIndex - 1;\r\n }\r\n\r\n // Si la raíz está presente en el historial de la raíz\r\n function isKnownRoot(bytes32 _root) public view returns (bool) {\r\n if (_root == 0) return false;\r\n\r\n uint32 i = currentRootIndex;\r\n do {\r\n if (_root == roots[i]) return true;\r\n if (i == 0) i = ROOT_HISTORY_SIZE;\r\n i--;\r\n } while (i != currentRootIndex);\r\n return false;\r\n }\r\n\r\n function getLastRoot() public view returns (bytes32) {\r\n return roots[currentRootIndex];\r\n }\r\n}\r\n" + }, + "contracts/ZKATM_Token.sol": { + "content": "// SPDX-License-Identifier: MIT\r\n// Compatible with OpenZeppelin Contracts ^5.0.0\r\npragma solidity >=0.8.20 <0.9.0;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\n\r\ncontract ZKATM_Token is ERC20, ERC20Pausable, Ownable {\r\n string public greeting = \"Deploy token ZKATM\";\r\n address public atmAddress;\r\n\r\n constructor(address initialOwner)\r\n ERC20(\"ZKATM_Token\", \"ZKATM\")\r\n Ownable(initialOwner)\r\n {\r\n _mint(msg.sender, 1000000 * 10 ** decimals());\r\n }\r\n \r\n function updateATMAddress(address _atm) external onlyOwner {\r\n atmAddress = _atm;\r\n }\r\n\r\n function pause() public onlyOwner {\r\n _pause();\r\n }\r\n\r\n function unpause() public onlyOwner {\r\n _unpause();\r\n }\r\n\r\n function mint(address to, uint256 amount) public onlyATM {\r\n _mint(to, amount);\r\n }\r\n\r\n // The following functions are overrides required by Solidity.\r\n\r\n function _update(address from, address to, uint256 value)\r\n internal\r\n override(ERC20, ERC20Pausable)\r\n {\r\n super._update(from, to, value);\r\n }\r\n\r\n modifier onlyATM(){\r\n require(msg.sender == atmAddress, \"only_atm\");\r\n _;\r\n }\r\n}\r\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/scrollSepolia/solcInputs/817e836a0999b6e54f819deada35718d.json b/packages/hardhat/deployments/scrollSepolia/solcInputs/817e836a0999b6e54f819deada35718d.json new file mode 100644 index 0000000..175602f --- /dev/null +++ b/packages/hardhat/deployments/scrollSepolia/solcInputs/817e836a0999b6e54f819deada35718d.json @@ -0,0 +1,66 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../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 * The initial owner is set to the address provided by the deployer. This can\n * 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 /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\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 if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n * ```\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ERC20} from \"../ERC20.sol\";\nimport {Pausable} from \"../../../utils/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract pause mechanism of the contract unreachable, and thus unusable.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_update}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {\n super._update(from, to, value);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\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 function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n bool private _paused;\n\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n /**\n * @dev The operation failed because the contract is paused.\n */\n error EnforcedPause();\n\n /**\n * @dev The operation failed because the contract is not paused.\n */\n error ExpectedPause();\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n if (paused()) {\n revert EnforcedPause();\n }\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n if (!paused()) {\n revert ExpectedPause();\n }\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "contracts/ATM.sol": { + "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.8.0 <0.9.0;\r\nimport \"./MerkleTree.sol\";\r\nimport \"./ZKATM_Token.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\"; // Importar interfaz del token ERC20\r\n\r\nstruct Proof {\r\n uint256[2] a;\r\n uint256[2][2] b;\r\n uint256[2] c;\r\n}\r\n\r\ninterface IVerifier {\r\n function verifyProof(\r\n\t\tuint256[2] calldata a, \r\n \t\tuint256[2][2] calldata b,\r\n uint256[2] calldata c,\r\n\t\tuint256[2] memory _input\r\n\t) external returns (bool);\r\n}\r\n\r\ncontract ATM is MerkleTree {\r\n\tuint256 public immutable denomination;\r\n\tIVerifier public immutable verifier;\r\n\tuint256 public balanceTotalATM;\r\n\tZKATM_Token public zkatmToken; // referencia del token ZKATM\r\n\tmapping (address _account => uint256 _balance) public balance;\r\n\tmapping (bytes32 => bool) public nullifierHashes;\r\n\tmapping (address _account => bool) public initialized;\r\n\t// almacenar compromisos para evitar depósitos accidentales con el mismo compromiso.\r\n\tmapping(bytes32 => bool) public commitments; \t\t\t\t\t\t \r\n\tstring public greeting = \"Starting to build my ZKATM proyect!!!\";\r\n\t// _verifier --> la dirección del contrato verificador para este SNARK\r\n\t// _hasher --> la dirección del contrato hash poseidon \r\n\t// _denomination --> cantidad a transferir por cada deposito\r\n // _merkleTreeHeight --> la altura del árbol Merkle de los depósitos\r\n\t// Hasher address (Poseidon 1 args): 0xCc735e52E393f125cAFc4E0aEbD80AEd81eA4B41\r\n\t// Verifier address: 0x0918fe077e800b24E1D64c2FE9bb6a12E0255CA9\r\n\t\r\n\tconstructor(\r\n \tIVerifier _verifier,\r\n\t\taddress _hasher,\r\n\t\tuint256 _denomination,\r\n \tuint32 _merkleTreeHeight,\r\n\t\tZKATM_Token _zkatmToken // Añade este parámetro para el token ZKATM\r\n \t)MerkleTree(_merkleTreeHeight, _hasher){\r\n \tverifier = _verifier;\r\n\t\thasher = Hasher(_hasher);\r\n\t\tdenomination = _denomination;\r\n\t\tzkatmToken = _zkatmToken; // Inicializa la referencia del token ZKATM\r\n \t}\r\n\r\n\tfunction initializeBalance() external {\r\n require(!initialized[msg.sender], \"El saldo ya ha sido inicializado\");\r\n\t\t// Transferir 50 tokens ZKATM al usuario que llama la función\r\n uint256 tokenAmount = 50 * (10 ** zkatmToken.decimals()); // Ajuste según los decimales del token\r\n zkatmToken.mint(msg.sender, tokenAmount);\r\n\t\tinitialized[msg.sender] = true;\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n }\r\n\r\n event Deposit (address from, uint32 leafIndex, uint256 value, uint256 timestamp);\r\n event Transfer (address from, address to, uint256 value, uint256 timestamp);\r\n event Withdraw (address to, bytes32 _nullifierHash, uint256 value);\r\n\t\r\n error InsufficientBalance();\r\n\r\n\tfunction generateCommitment() public view returns (\r\n\t\tbytes32 nullifier, \r\n\t\tbytes32 secret,\r\n\t \tbytes32 commitment, \r\n\t\tbytes32 nullifierHash\r\n\t\t) {\r\n\t\t// Puedes ajustar cómo generas el nullifier\r\n nullifier = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \r\n\t\t// Puedes ajustar cómo generas el secret\r\n secret = bytes32(uint256(keccak256(abi.encodePacked(nullifier, block.timestamp, msg.sender))) % MerkleTree.FIELD_SIZE); \r\n\t\tcommitment = hasher.poseidon([nullifier, secret]);\r\n nullifierHash = hasher.poseidon([nullifier, nullifier]);\r\n }\r\n\r\n\t// commitment el compromiso de nota, que es poseidonhash(anulador + secreto)\r\n function deposit(bytes32 commitment, uint256 _amount) public {\r\n\t\trequire(!commitments[commitment], \"El compromiso ya se ha insertado\");\r\n\t\tif(zkatmToken.balanceOf(msg.sender) < _amount) revert InsufficientBalance();\r\n\t\trequire(_amount == (denomination * (10 ** zkatmToken.decimals())), \"La cantidad depositada no es admitida\");\r\n\t\t\r\n\t\t// Transfiere los tokens desde el usuario que llama a la función hacia este contrato\r\n \tbool transferSuccess = zkatmToken.transferFrom(msg.sender, address(this), _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n\t\tuint32 insertedIndex = _insert(commitment);\r\n\t\tcommitments[commitment] = true;\r\n\t\tbalanceTotalATM += _amount;\r\n\t\temit Deposit (msg.sender, insertedIndex, balance[msg.sender], block.timestamp);\r\n\t}\r\n\r\n\t// _proof --> son datos de la prueba zkSNARK y la entrada es una matriz de entradas públicas del circuito.\r\n\t// _input --> un array del cicuito con las siguientes entradas publicas:\r\n // - raíz merkle de todos los depósitos en el contrato\r\n // - hash de anulador de depósito único para evitar gastos dobles\r\n function withdraw(uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\r\n\t\trequire(_amount == denomination, \"La cantidad a retirar no es admitida\");\r\n\t\trequire(!nullifierHashes[_nullifierHash], \"La nota ya fue gastada\");\r\n\t\trequire(isKnownRoot(_root), \"No puedo encontrar la raiz de merkle\"); //Asegúrate de usar uno de los ultimos 3 reciente\r\n\t\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \"Prueba para retirar no valida\");\r\n\t\tnullifierHashes[_nullifierHash] = true;\r\n\r\n\t\t// Transfiere los tokens desde el contrato al usuario que llama a la función\r\n \tbool transferSuccess = zkatmToken.transfer(msg.sender, _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\t\t\r\n\t\tbalance[msg.sender] = zkatmToken.balanceOf(msg.sender);\r\n\t\tbalanceTotalATM -= _amount;\r\n\t\temit Withdraw (msg.sender, _nullifierHash, _amount);\r\n\t}\r\n\r\n function transfer(address _receiver, uint256 _amount, Proof calldata _proof, bytes32 _root, bytes32 _nullifierHash) public {\r\n\t\trequire(_amount == denomination, \"La cantidad a retirar no es admitida\");\r\n\t\trequire(!nullifierHashes[_nullifierHash], \"La nota ya fue gastada\");\r\n\t\trequire(isKnownRoot(_root), \"No puedo encontrar la raiz de merkle\"); //Asegúrate de usar uno de los ultimos 3 reciente\r\n\t\trequire(verifier.verifyProof(_proof.a, _proof.b, _proof.c, [uint256(_root), uint256(_nullifierHash)]), \"Prueba para retirar no valida\");\r\n\t\tnullifierHashes[_nullifierHash] = true;\r\n\r\n\t\t// Transfiere los tokens desde el contrato al usuario que llama a la función\r\n \tbool transferSuccess = zkatmToken.transfer(_receiver, _amount);\r\n \trequire(transferSuccess, \"La transferencia de tokens ha fallado\");\r\n\t\tbalance[_receiver] = zkatmToken.balanceOf(_receiver);\r\n\t\tbalanceTotalATM -= _amount;\r\n\t\temit Transfer (msg.sender, _receiver, _amount, block.timestamp);\r\n\t}\r\n\t function isSpent(bytes32 _nullifierHash) public view returns (bool) {\r\n return nullifierHashes[_nullifierHash];\r\n } \r\n}\r\n" + }, + "contracts/MerkleTree.sol": { + "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\ninterface Hasher {\r\n function poseidon(bytes32[2] calldata leftRight) external pure returns (bytes32);\r\n}\r\n\r\ncontract MerkleTree {\r\n uint256 public constant FIELD_SIZE =\r\n 21888242871839275222246405745257275088548364400416034343698204186575808495617; // orden (cardinalidad) de la curva\r\n uint256 public constant ZERO_VALUE =\r\n 13187267684982673088682801604133345722716467932170606900401783776316647633885; // = keccak256(\"MiATM\") % FIELD_SIZE\r\n\r\n Hasher public hasher;\r\n uint32 public immutable levels;\r\n\r\n // las siguientes variables se hacen públicas para facilitar las pruebas y\r\n // se que no se debe acceder a ellas mediante código normal\r\n bytes32[] public filledSubtrees; // arreglo con roots del subarbol a la izquierda de una hoja (de tamaño _levels)\r\n bytes32[] public zeros; // arreglo con roots del subarbol a la derecha de una hoja (de tamaño _levels)\r\n uint32 public currentRootIndex = 0;\r\n uint32 public nextIndex = 0;\r\n uint32 public constant ROOT_HISTORY_SIZE = 3; // tiene que ser menor que 2**levels (cada nueva hoja nueva raíz)\r\n bytes32[ROOT_HISTORY_SIZE] public roots;\r\n\r\n constructor(uint32 _levels, address _hasher) {\r\n require(_levels > 0, \"_levels debe ser mayor que cero\");\r\n require(_levels < 6, \"_levels debe ser menor que 6\");\r\n levels = _levels;\r\n hasher = Hasher(_hasher);\r\n \r\n bytes32 currentZero = bytes32(ZERO_VALUE);\r\n zeros.push(currentZero);\r\n filledSubtrees.push(currentZero);\r\n\r\n // Obteniendo la primera raiz para todas las hojas vacias\r\n for (uint32 i = 1; i < _levels; i++) {\r\n currentZero = hashLeftRight(currentZero, currentZero);\r\n zeros.push(currentZero); \r\n filledSubtrees.push(currentZero);\r\n }\r\n\r\n roots[0] = hashLeftRight(currentZero, currentZero); // comentar raiz predeterminada siempre es la misma dependiedo del nivel\r\n }\r\n\r\n // Hasheando 2 hojas del árbol, devuelve poseidon(leftright)\r\n function hashLeftRight(bytes32 _left, bytes32 _right) public view returns (bytes32) {\r\n require(uint256(_left) < FIELD_SIZE, \"_left debe estar dentro del campo\" );\r\n require(uint256(_right) < FIELD_SIZE, \"_right debe estar dentro del campo\" );\r\n bytes32[2] memory leftright = [_left, _right];\r\n return hasher.poseidon(leftright);\r\n }\r\n\r\n function _insert(bytes32 _leaf) internal returns (uint32 index) {\r\n uint32 currentIndex = nextIndex;\r\n require(currentIndex != uint32(2)**levels, \"Arbol Merkle lleno. No se pueden agregar hojas.\");\r\n nextIndex += 1;\r\n bytes32 currentLevelHash = _leaf;\r\n bytes32 left;\r\n bytes32 right;\r\n\r\n for (uint32 i = 0; i < levels; i++) {\r\n if (currentIndex % 2 == 0) {\r\n left = currentLevelHash;\r\n right = zeros[i];\r\n \r\n filledSubtrees[i] = currentLevelHash;\r\n } else {\r\n left = filledSubtrees[i];\r\n right = currentLevelHash;\r\n }\r\n\r\n currentLevelHash = hashLeftRight(left, right);\r\n\r\n currentIndex /= 2;\r\n }\r\n\r\n currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\r\n roots[currentRootIndex] = currentLevelHash;\r\n return nextIndex - 1;\r\n }\r\n\r\n // Si la raíz está presente en el historial de la raíz\r\n function isKnownRoot(bytes32 _root) public view returns (bool) {\r\n if (_root == 0) return false;\r\n\r\n uint32 i = currentRootIndex;\r\n do {\r\n if (_root == roots[i]) return true;\r\n if (i == 0) i = ROOT_HISTORY_SIZE;\r\n i--;\r\n } while (i != currentRootIndex);\r\n return false;\r\n }\r\n\r\n function getLastRoot() public view returns (bytes32) {\r\n return roots[currentRootIndex];\r\n }\r\n}\r\n" + }, + "contracts/ZKATM_Token.sol": { + "content": "// SPDX-License-Identifier: MIT\r\n// Compatible with OpenZeppelin Contracts ^5.0.0\r\npragma solidity >=0.8.20 <0.9.0;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\n\r\ncontract ZKATM_Token is ERC20, ERC20Pausable, Ownable {\r\n string public greeting = \"Deploy token ZKATM\";\r\n address public atmAddress;\r\n\r\n constructor(address initialOwner)\r\n ERC20(\"ZKATM_Token\", \"ZKATM\")\r\n Ownable(initialOwner)\r\n {\r\n _mint(msg.sender, 1000000 * 10 ** decimals());\r\n }\r\n \r\n function updateATMAddress(address _atm) external onlyOwner {\r\n atmAddress = _atm;\r\n }\r\n\r\n function pause() public onlyOwner {\r\n _pause();\r\n }\r\n\r\n function unpause() public onlyOwner {\r\n _unpause();\r\n }\r\n\r\n function mint(address to, uint256 amount) public onlyATM {\r\n _mint(to, amount);\r\n }\r\n\r\n // The following functions are overrides required by Solidity.\r\n\r\n function _update(address from, address to, uint256 value)\r\n internal\r\n override(ERC20, ERC20Pausable)\r\n {\r\n super._update(from, to, value);\r\n }\r\n\r\n modifier onlyATM(){\r\n require(msg.sender == atmAddress, \"only_atm\");\r\n _;\r\n }\r\n}\r\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/test/YourContract.ts b/packages/hardhat/test/YourContract.ts deleted file mode 100644 index a44cf04..0000000 --- a/packages/hardhat/test/YourContract.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { expect } from "chai"; -import { ethers } from "hardhat"; -import { YourContract } from "../typechain-types"; - -describe("YourContract", function () { - // We define a fixture to reuse the same setup in every test. - - let yourContract: YourContract; - before(async () => { - const [owner] = await ethers.getSigners(); - const yourContractFactory = await ethers.getContractFactory("YourContract"); - yourContract = (await yourContractFactory.deploy(owner.address)) as YourContract; - await yourContract.waitForDeployment(); - }); - - describe("Deployment", function () { - it("Should have the right message on deploy", async function () { - expect(await yourContract.greeting()).to.equal("Building Unstoppable Apps!!!"); - }); - - it("Should allow setting a new message", async function () { - const newGreeting = "Learn Scaffold-ETH 2! :)"; - - await yourContract.setGreeting(newGreeting); - expect(await yourContract.greeting()).to.equal(newGreeting); - }); - }); -}); diff --git a/packages/nextjs/.gitignore b/packages/nextjs/.gitignore index 917f1d6..eeb55b2 100644 --- a/packages/nextjs/.gitignore +++ b/packages/nextjs/.gitignore @@ -36,3 +36,5 @@ yarn-error.log* # typescript *.tsbuildinfo .vercel + +.vercel diff --git a/packages/nextjs/app/atm/deposit/page.tsx b/packages/nextjs/app/atm/deposit/page.tsx index 0130098..448fc39 100644 --- a/packages/nextjs/app/atm/deposit/page.tsx +++ b/packages/nextjs/app/atm/deposit/page.tsx @@ -36,7 +36,8 @@ const AtmDeposit: NextPage = () => { } }); - const { writeContractAsync: sendAction } = useScaffoldWriteContract("ATM"); + const { writeContractAsync: deposit } = useScaffoldWriteContract("ATM"); + const { writeContractAsync: initialized, isSuccess, isPending } = useScaffoldWriteContract("ATM"); const handleGenerate = useCallback(_handleGenerate, [comitment_isRefetch]) @@ -89,7 +90,7 @@ const AtmDeposit: NextPage = () => { } -
+ +
+ +
- async function _handleGenerate() { @@ -127,7 +137,7 @@ const AtmDeposit: NextPage = () => { async function handleDeposit(data: TDeposit) { try { - await sendAction({ + await deposit({ functionName: "deposit", args: [data.commitment, BigInt(data.ammount)] }); @@ -137,6 +147,17 @@ const AtmDeposit: NextPage = () => { console.error(e) } } + + async function handleInitialized() { + if(isSuccess || isPending) return; + try{ + await initialized({ + functionName: "initializeBalance", + }) + } catch(e){ + console.error(e) + } + } } export default AtmDeposit diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts index 52046b8..bfda6e0 100644 --- a/packages/nextjs/contracts/deployedContracts.ts +++ b/packages/nextjs/contracts/deployedContracts.ts @@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract"; const deployedContracts = { 534351: { ATM: { - address: "0x2b912c55769B50ca71834774f808143513769969", + address: "0x7c05E68f0A835459D82532756E7c932cc0aA607f", abi: [ { inputs: [ @@ -805,7 +805,7 @@ const deployedContracts = { inheritedFunctions: {}, }, ZKATM_Token: { - address: "0xDD8fA77500F94b2286AbE41c81B4a08EdD0429B9", + address: "0x4c0Fd51D88216250507Ec303ACbE76473a19AfE9", abi: [ { inputs: [