From 82f3f7849661823905df2011776d7239df996e89 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 29 Nov 2022 16:34:10 +0100 Subject: [PATCH 1/5] Update wallet container URLs to arbitrum goerli --- wallet.Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wallet.Dockerfile b/wallet.Dockerfile index bfb03ce8..6a05f6d0 100644 --- a/wallet.Dockerfile +++ b/wallet.Dockerfile @@ -13,9 +13,9 @@ RUN chmod +x /app/wallet-cli # Point at the Goerli testnet deployment by default; all of these settings can be overridden with # command line options. -ENV CAPE_EQS_URL=https://eqs.goerli.cape.tech -ENV CAPE_RELAYER_URL=https://relayer.goerli.cape.tech -ENV CAPE_ADDRESS_BOOK_URL=https://address-book.goerli.cape.tech +ENV CAPE_EQS_URL=https://eqs.arbitrum-goerli.cape.tech +ENV CAPE_RELAYER_URL=https://relayer.arbitrum-goerli.cape.tech +ENV CAPE_ADDRESS_BOOK_URL=https://address-book.arbitrum-goerli.cape.tech # Set the storage directory to allow the wallet to access the official assets library. ENV CAPE_WALLET_STORAGE=/.espresso From b82d72d68e56c810ca2cfeda9459de48012c0a21 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 30 Nov 2022 17:39:13 +0100 Subject: [PATCH 2/5] Add mintable tokens and a test for them. - Remove funding the deployer from all tokens except SimpleToken. - Add instructions for how to deploy tokens to arbitrum. - Use 6 decimals for USDC and the default (18) for the others. --- README.md | 7 ++++ contracts/contracts/SimpleToken.sol | 5 ++- contracts/contracts/USDC.sol | 4 ++ contracts/contracts/WrapToken.sol | 16 +++---- contracts/deploy/10_token.ts | 17 +++++--- contracts/test/token.spec.ts | 65 +++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 contracts/test/token.spec.ts diff --git a/README.md b/README.md index 14eefde7..f1fc499d 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ describes the project at a high level. - [Testnets](#testnets) - [Goerli](#goerli) - [Running the smoke tests](#running-the-smoke-tests) +- [Arbitrum on Goerli](#arbitrum-on-goerli) ## Obtaining the source code @@ -705,3 +706,9 @@ project and use their arbitrum goerli RPC and use it via ``` CAPE_WEB3_PROVIDER_URL=https://arbitrum-goerli.infura.io/v3/... run-tests-arbitrum ``` + +To deploy mintable tokens that users can mint by sending Ether to it run + +``` +hardhat deploy --tags Token --network arbitrum_goerli --reset +``` diff --git a/contracts/contracts/SimpleToken.sol b/contracts/contracts/SimpleToken.sol index c926602a..2fc07bf7 100644 --- a/contracts/contracts/SimpleToken.sol +++ b/contracts/contracts/SimpleToken.sol @@ -12,5 +12,8 @@ pragma solidity ^0.8.0; import "./WrapToken.sol"; contract SimpleToken is WrapToken { - constructor() WrapToken("Simple Token", "SIT") {} + /// @notice The deployer receives 1e9 units. + constructor() WrapToken("Simple Token", "SIT") { + _mint(msg.sender, 1_000_000_000); + } } diff --git a/contracts/contracts/USDC.sol b/contracts/contracts/USDC.sol index 98c62168..f580a6c9 100644 --- a/contracts/contracts/USDC.sol +++ b/contracts/contracts/USDC.sol @@ -13,4 +13,8 @@ import "./WrapToken.sol"; contract USDC is WrapToken { constructor() WrapToken("USD Coin", "USDC") {} + + function decimals() public pure override returns (uint8) { + return 6; + } } diff --git a/contracts/contracts/WrapToken.sol b/contracts/contracts/WrapToken.sol index 9dccf539..10aecc1f 100644 --- a/contracts/contracts/WrapToken.sol +++ b/contracts/contracts/WrapToken.sol @@ -15,24 +15,18 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; /// @notice This token is only intended to be used for testing. contract WrapToken is ERC20 { - /// @notice The caller of this method receives 1000*10**6 units. - constructor(string memory name, string memory symbol) ERC20(name, symbol) { - _mint(msg.sender, 1000 * 10**6); - } + constructor(string memory name, string memory symbol) ERC20(name, symbol) {} /// @notice Allows minting tokens by sending Ether to it. receive() external payable { - _mint(msg.sender, 10**6 * msg.value); - } - - function decimals() public view virtual override returns (uint8) { - return 6; + uint256 amount = msg.value / 10**(18 - decimals()); + _mint(msg.sender, amount); } - function withdraw() external payable { + function withdraw() external { uint256 balance = balanceOf(msg.sender); address payable sender = payable(msg.sender); _burn(sender, balance); - sender.transfer(balance / 10**6); + sender.transfer(balance * 10**(18 - decimals())); } } diff --git a/contracts/deploy/10_token.ts b/contracts/deploy/10_token.ts index 497efd1c..4cec5e5e 100644 --- a/contracts/deploy/10_token.ts +++ b/contracts/deploy/10_token.ts @@ -10,13 +10,18 @@ import { DeployFunction } from "hardhat-deploy/types"; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; - const { deploy } = deployments; - const { tokenOwner } = await getNamedAccounts(); + const { deploy, log, read, execute } = deployments; + const { deployer } = await getNamedAccounts(); - await deploy("SimpleToken", { from: tokenOwner, log: true }); - await deploy("WETH", { from: tokenOwner, log: true }); - await deploy("DAI", { from: tokenOwner, log: true }); - await deploy("USDC", { from: tokenOwner, log: true }); + const deployToken = async (name: string) => { + await deploy(name, { from: deployer, log: true }); + let decimals = await read(name, "decimals"); + log(`Deployed with ${decimals} decimals`); + }; + + await deployToken("WETH"); + await deployToken("DAI"); + await deployToken("USDC"); }; export default func; diff --git a/contracts/test/token.spec.ts b/contracts/test/token.spec.ts new file mode 100644 index 00000000..b96f4f37 --- /dev/null +++ b/contracts/test/token.spec.ts @@ -0,0 +1,65 @@ +// Copyright (c) 2022 Espresso Systems (espressosys.com) +// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library. +// +// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// You should have received a copy of the GNU General Public License along with this program. If not, see . + +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { BigNumber, BigNumberish } from "ethers"; +const { utils } = ethers; + +describe("Token", function () { + let contract: any; + + beforeEach(async () => { + const factory = await ethers.getContractFactory("USDC"); + contract = await factory.deploy(); + }); + + it("Mints and withdraws correctly", async function () { + const [owner] = await ethers.getSigners(); + const provider = new ethers.providers.JsonRpcProvider(); + const decimals = await contract.decimals(); + let receipts = []; + + let beforeEther = await provider.getBalance(owner.address); + let beforeToken = await contract.balanceOf(owner.address); + + // Wrap some Ether. + const etherAmount = BigNumber.from("123"); + const tokenAmount = utils.parseUnits(etherAmount.toString(), decimals); + let tx = await owner.sendTransaction({ + to: contract.address, + value: utils.parseEther(etherAmount.toString()), + }); + await tx.wait(); + receipts.push(await provider.getTransactionReceipt(tx.hash)); + + let afterToken = await contract.balanceOf(owner.address); + + expect(afterToken).to.equal(beforeToken.add(tokenAmount)); + + // Unwrap the tokens back into Ether. + tx = await contract.withdraw({ gasLimit: 1000000 }); // unpredictable gas limit due to storage free + await tx.wait(); + receipts.push(await provider.getTransactionReceipt(tx.hash)); + + const gasFee = receipts.reduce((acc, receipt) => { + return acc.add(receipt.gasUsed.mul(receipt.effectiveGasPrice)); + }, BigNumber.from(0)); + + // Token balance is zero. + expect(await contract.balanceOf(owner.address)).to.equal(0); + + // Contract has zero Ether. + expect(await contract.balanceOf(contract.address)).to.equal(0); + + // Note: This test can get flaky if geth has been running for a long time + // and the last check may fail in that case. + + // Ether balance is the same as originally (minus gas fees) + expect(await provider.getBalance(owner.address)).to.equal(beforeEther.sub(gasFee)); + }); +}); From f13e8694fd5c2157ce86331bf36b427608a75203 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 30 Nov 2022 18:24:12 +0100 Subject: [PATCH 3/5] Comment out flaky expect --- contracts/test/token.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/test/token.spec.ts b/contracts/test/token.spec.ts index b96f4f37..080c9a3c 100644 --- a/contracts/test/token.spec.ts +++ b/contracts/test/token.spec.ts @@ -57,9 +57,9 @@ describe("Token", function () { expect(await contract.balanceOf(contract.address)).to.equal(0); // Note: This test can get flaky if geth has been running for a long time - // and the last check may fail in that case. + // and the last check may fail in that case. It's therefore currently disabled. // Ether balance is the same as originally (minus gas fees) - expect(await provider.getBalance(owner.address)).to.equal(beforeEther.sub(gasFee)); + // expect(await provider.getBalance(owner.address)).to.equal(beforeEther.sub(gasFee)); }); }); From 308a00ab8c617c8a1cd49ef946379e0e3da83b19 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 30 Nov 2022 20:07:40 +0100 Subject: [PATCH 4/5] Deploy token contracts on arbitrum goerli --- README.md | 8 + .../deployments/arbitrum_goerli/.chainId | 1 + .../deployments/arbitrum_goerli/DAI.json | 432 ++++++++++++++++++ .../deployments/arbitrum_goerli/USDC.json | 432 ++++++++++++++++++ .../deployments/arbitrum_goerli/WETH.json | 432 ++++++++++++++++++ .../3fcb829bdff3dbd1d10e0f68ff789618.json | 188 ++++++++ 6 files changed, 1493 insertions(+) create mode 100644 contracts/deployments/arbitrum_goerli/.chainId create mode 100644 contracts/deployments/arbitrum_goerli/DAI.json create mode 100644 contracts/deployments/arbitrum_goerli/USDC.json create mode 100644 contracts/deployments/arbitrum_goerli/WETH.json create mode 100644 contracts/deployments/arbitrum_goerli/solcInputs/3fcb829bdff3dbd1d10e0f68ff789618.json diff --git a/README.md b/README.md index f1fc499d..a6f35522 100644 --- a/README.md +++ b/README.md @@ -712,3 +712,11 @@ To deploy mintable tokens that users can mint by sending Ether to it run ``` hardhat deploy --tags Token --network arbitrum_goerli --reset ``` + +The currently deployed token contracts on arbitrum goerli are + +```console +WETH 0x4F1D9E040cf28A522ec79951cDb7B55c8aE4744E +DAI 0xBeec50ed16E3559afCD582cC98ed2b5F5DcA189E +USDC 0x9A4f4Ee35a8FfEE459B3187A372d422790fc8aAB +``` diff --git a/contracts/deployments/arbitrum_goerli/.chainId b/contracts/deployments/arbitrum_goerli/.chainId new file mode 100644 index 00000000..16be23a3 --- /dev/null +++ b/contracts/deployments/arbitrum_goerli/.chainId @@ -0,0 +1 @@ +421613 \ No newline at end of file diff --git a/contracts/deployments/arbitrum_goerli/DAI.json b/contracts/deployments/arbitrum_goerli/DAI.json new file mode 100644 index 00000000..ba366282 --- /dev/null +++ b/contracts/deployments/arbitrum_goerli/DAI.json @@ -0,0 +1,432 @@ +{ + "address": "0xBeec50ed16E3559afCD582cC98ed2b5F5DcA189E", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xe7bfb725216fc5d11bf653ffc6458075c185c944ad2851358b9bca048c2e593c", + "receipt": { + "to": null, + "from": "0x902Fdb7c1EAbfcCB08321db1Fb5b54099a473CE1", + "contractAddress": "0xBeec50ed16E3559afCD582cC98ed2b5F5DcA189E", + "transactionIndex": 1, + "gasUsed": "914387", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7c336be454d257a2df9959e7273c5ab8054eced33602252ba76c5381696c56ba", + "transactionHash": "0xe7bfb725216fc5d11bf653ffc6458075c185c944ad2851358b9bca048c2e593c", + "logs": [], + "blockNumber": 2030833, + "cumulativeGasUsed": "914387", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3fcb829bdff3dbd1d10e0f68ff789618", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DaiToken.sol\":\"DAI\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\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\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/DaiToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WrapToken.sol\\\";\\n\\ncontract DAI is WrapToken {\\n constructor() WrapToken(\\\"DAI Token\\\", \\\"DAI\\\") {}\\n}\\n\",\"keccak256\":\"0x6b735bfae161e4c8cedec0de9a431fc395535a064a4b0344ceee16f47880f5bb\",\"license\":\"GPL-3.0-or-later\"},\"contracts/WrapToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\n// Learn more about the ERC20 implementation\\n// on OpenZeppelin docs: https://docs.openzeppelin.com/contracts/4.x/erc20\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n/// @notice This token is only intended to be used for testing.\\ncontract WrapToken is ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @notice Allows minting tokens by sending Ether to it.\\n receive() external payable {\\n uint256 amount = msg.value / 10**(18 - decimals());\\n _mint(msg.sender, amount);\\n }\\n\\n function withdraw() external {\\n uint256 balance = balanceOf(msg.sender);\\n address payable sender = payable(msg.sender);\\n _burn(sender, balance);\\n sender.transfer(balance * 10**(18 - decimals()));\\n }\\n}\\n\",\"keccak256\":\"0x4562db1d9ba68b5e97dad77d9b83795933575e3ad92ebe1961ba99f0decc7dca\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604051806040016040528060098152602001682220a4902a37b5b2b760b91b8152506040518060400160405280600381526020016244414960e81b815250818181600390805190602001906200006a9291906200008b565b508051620000809060049060208401906200008b565b50505050506200016d565b828054620000999062000131565b90600052602060002090601f016020900481019282620000bd576000855562000108565b82601f10620000d857805160ff191683800117855562000108565b8280016001018555821562000108579182015b8281111562000108578251825591602001919060010190620000eb565b50620001169291506200011a565b5090565b5b808211156200011657600081556001016200011b565b600181811c908216806200014657607f821691505b6020821081036200016757634e487b7160e01b600052602260045260246000fd5b50919050565b610eb8806200017d6000396000f3fe6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023b578063a9059cbb1461025b578063dd62ed3e1461027b57600080fd5b80633ccfd60b146101db57806370a08231146101f057806395d89b411461022657600080fd5b806323b872dd116100a557806323b872dd1461017f578063313ce5671461019f57806339509351146101bb57600080fd5b806306fdde0314610105578063095ea7b31461013057806318160ddd1461016057600080fd5b366101005760006100dd601280610b96565b6100e890600a610c9d565b6100f29034610cb3565b90506100fe33826102c1565b005b600080fd5b34801561011157600080fd5b5061011a6103a5565b6040516101279190610cd5565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004610d46565b610437565b6040519015158152602001610127565b34801561016c57600080fd5b506002545b604051908152602001610127565b34801561018b57600080fd5b5061015061019a366004610d70565b61044e565b3480156101ab57600080fd5b5060405160128152602001610127565b3480156101c757600080fd5b506101506101d6366004610d46565b61050d565b3480156101e757600080fd5b506100fe610549565b3480156101fc57600080fd5b5061017161020b366004610dac565b6001600160a01b031660009081526020819052604090205490565b34801561023257600080fd5b5061011a6105be565b34801561024757600080fd5b50610150610256366004610d46565b6105cd565b34801561026757600080fd5b50610150610276366004610d46565b61067e565b34801561028757600080fd5b50610171610296366004610dc7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031c5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032e9190610dfa565b90915550506001600160a01b0382166000908152602081905260408120805483929061035b908490610dfa565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b490610e12565b80601f01602080910402602001604051908101604052809291908181526020018280546103e090610e12565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044433848461068b565b5060015b92915050565b600061045b8484846107e3565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f55760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610313565b610502853385840361068b565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610444918590610544908690610dfa565b61068b565b336000818152602081905260409020549061056481836109fb565b6001600160a01b0381166108fc61057c601280610b96565b61058790600a610c9d565b6105919085610e4c565b6040518115909202916000818181858888f193505050501580156105b9573d6000803e3d6000fd5b505050565b6060600480546103b490610e12565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106675760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610313565b610674338585840361068b565b5060019392505050565b60006104443384846107e3565b6001600160a01b0383166107065760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166107825760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661085f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166108db5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260409020548181101561096a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a1908490610dfa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ed91815260200190565b60405180910390a350505050565b6001600160a01b038216610a775760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b03821660009081526020819052604090205481811015610b065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b35908490610e6b565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb057610bb0610b80565b90039392505050565b600181815b80851115610bf4578160001904821115610bda57610bda610b80565b80851615610be757918102915b93841c9390800290610bbe565b509250929050565b600082610c0b57506001610448565b81610c1857506000610448565b8160018114610c2e5760028114610c3857610c54565b6001915050610448565b60ff841115610c4957610c49610b80565b50506001821b610448565b5060208310610133831016604e8410600b8410161715610c77575081810a610448565b610c818383610bb9565b8060001904821115610c9557610c95610b80565b029392505050565b6000610cac60ff841683610bfc565b9392505050565b600082610cd057634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0257858101830151858201604001528201610ce6565b81811115610d14576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4157600080fd5b919050565b60008060408385031215610d5957600080fd5b610d6283610d2a565b946020939093013593505050565b600080600060608486031215610d8557600080fd5b610d8e84610d2a565b9250610d9c60208501610d2a565b9150604084013590509250925092565b600060208284031215610dbe57600080fd5b610cac82610d2a565b60008060408385031215610dda57600080fd5b610de383610d2a565b9150610df160208401610d2a565b90509250929050565b60008219821115610e0d57610e0d610b80565b500190565b600181811c90821680610e2657607f821691505b602082108103610e4657634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6657610e66610b80565b500290565b600082821015610e7d57610e7d610b80565b50039056fea2646970667358221220a680fc439bb3c5c2778ab038866b45f8c13e946f19c89e61c020132a92d46ce464736f6c634300080d0033", + "deployedBytecode": "0x6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023b578063a9059cbb1461025b578063dd62ed3e1461027b57600080fd5b80633ccfd60b146101db57806370a08231146101f057806395d89b411461022657600080fd5b806323b872dd116100a557806323b872dd1461017f578063313ce5671461019f57806339509351146101bb57600080fd5b806306fdde0314610105578063095ea7b31461013057806318160ddd1461016057600080fd5b366101005760006100dd601280610b96565b6100e890600a610c9d565b6100f29034610cb3565b90506100fe33826102c1565b005b600080fd5b34801561011157600080fd5b5061011a6103a5565b6040516101279190610cd5565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004610d46565b610437565b6040519015158152602001610127565b34801561016c57600080fd5b506002545b604051908152602001610127565b34801561018b57600080fd5b5061015061019a366004610d70565b61044e565b3480156101ab57600080fd5b5060405160128152602001610127565b3480156101c757600080fd5b506101506101d6366004610d46565b61050d565b3480156101e757600080fd5b506100fe610549565b3480156101fc57600080fd5b5061017161020b366004610dac565b6001600160a01b031660009081526020819052604090205490565b34801561023257600080fd5b5061011a6105be565b34801561024757600080fd5b50610150610256366004610d46565b6105cd565b34801561026757600080fd5b50610150610276366004610d46565b61067e565b34801561028757600080fd5b50610171610296366004610dc7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031c5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032e9190610dfa565b90915550506001600160a01b0382166000908152602081905260408120805483929061035b908490610dfa565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b490610e12565b80601f01602080910402602001604051908101604052809291908181526020018280546103e090610e12565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044433848461068b565b5060015b92915050565b600061045b8484846107e3565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f55760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610313565b610502853385840361068b565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610444918590610544908690610dfa565b61068b565b336000818152602081905260409020549061056481836109fb565b6001600160a01b0381166108fc61057c601280610b96565b61058790600a610c9d565b6105919085610e4c565b6040518115909202916000818181858888f193505050501580156105b9573d6000803e3d6000fd5b505050565b6060600480546103b490610e12565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106675760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610313565b610674338585840361068b565b5060019392505050565b60006104443384846107e3565b6001600160a01b0383166107065760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166107825760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661085f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166108db5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260409020548181101561096a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a1908490610dfa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ed91815260200190565b60405180910390a350505050565b6001600160a01b038216610a775760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b03821660009081526020819052604090205481811015610b065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b35908490610e6b565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb057610bb0610b80565b90039392505050565b600181815b80851115610bf4578160001904821115610bda57610bda610b80565b80851615610be757918102915b93841c9390800290610bbe565b509250929050565b600082610c0b57506001610448565b81610c1857506000610448565b8160018114610c2e5760028114610c3857610c54565b6001915050610448565b60ff841115610c4957610c49610b80565b50506001821b610448565b5060208310610133831016604e8410600b8410161715610c77575081810a610448565b610c818383610bb9565b8060001904821115610c9557610c95610b80565b029392505050565b6000610cac60ff841683610bfc565b9392505050565b600082610cd057634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0257858101830151858201604001528201610ce6565b81811115610d14576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4157600080fd5b919050565b60008060408385031215610d5957600080fd5b610d6283610d2a565b946020939093013593505050565b600080600060608486031215610d8557600080fd5b610d8e84610d2a565b9250610d9c60208501610d2a565b9150604084013590509250925092565b600060208284031215610dbe57600080fd5b610cac82610d2a565b60008060408385031215610dda57600080fd5b610de383610d2a565b9150610df160208401610d2a565b90509250929050565b60008219821115610e0d57610e0d610b80565b500190565b600181811c90821680610e2657607f821691505b602082108103610e4657634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6657610e66610b80565b500290565b600082821015610e7d57610e7d610b80565b50039056fea2646970667358221220a680fc439bb3c5c2778ab038866b45f8c13e946f19c89e61c020132a92d46ce464736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 159, + "contract": "contracts/DaiToken.sol:DAI", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 165, + "contract": "contracts/DaiToken.sol:DAI", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 167, + "contract": "contracts/DaiToken.sol:DAI", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 169, + "contract": "contracts/DaiToken.sol:DAI", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 171, + "contract": "contracts/DaiToken.sol:DAI", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/arbitrum_goerli/USDC.json b/contracts/deployments/arbitrum_goerli/USDC.json new file mode 100644 index 00000000..552b734f --- /dev/null +++ b/contracts/deployments/arbitrum_goerli/USDC.json @@ -0,0 +1,432 @@ +{ + "address": "0x9A4f4Ee35a8FfEE459B3187A372d422790fc8aAB", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xaf9e7071aa750e14f379f3e793871a10add86c9f199eeb69e3bcd38ee02d3c55", + "receipt": { + "to": null, + "from": "0x902Fdb7c1EAbfcCB08321db1Fb5b54099a473CE1", + "contractAddress": "0x9A4f4Ee35a8FfEE459B3187A372d422790fc8aAB", + "transactionIndex": 1, + "gasUsed": "914654", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0ea51391dcf5b7ff382212acb68d196ce58145ed60858af5235312a51ed1ab85", + "transactionHash": "0xaf9e7071aa750e14f379f3e793871a10add86c9f199eeb69e3bcd38ee02d3c55", + "logs": [], + "blockNumber": 2030839, + "cumulativeGasUsed": "914654", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3fcb829bdff3dbd1d10e0f68ff789618", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/USDC.sol\":\"USDC\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\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\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/USDC.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WrapToken.sol\\\";\\n\\ncontract USDC is WrapToken {\\n constructor() WrapToken(\\\"USD Coin\\\", \\\"USDC\\\") {}\\n\\n function decimals() public pure override returns (uint8) {\\n return 6;\\n }\\n}\\n\",\"keccak256\":\"0x9e2f059ea917a595092c02255899569528abab01c0fe757db6eb367debae9e6d\",\"license\":\"GPL-3.0-or-later\"},\"contracts/WrapToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\n// Learn more about the ERC20 implementation\\n// on OpenZeppelin docs: https://docs.openzeppelin.com/contracts/4.x/erc20\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n/// @notice This token is only intended to be used for testing.\\ncontract WrapToken is ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @notice Allows minting tokens by sending Ether to it.\\n receive() external payable {\\n uint256 amount = msg.value / 10**(18 - decimals());\\n _mint(msg.sender, amount);\\n }\\n\\n function withdraw() external {\\n uint256 balance = balanceOf(msg.sender);\\n address payable sender = payable(msg.sender);\\n _burn(sender, balance);\\n sender.transfer(balance * 10**(18 - decimals()));\\n }\\n}\\n\",\"keccak256\":\"0x4562db1d9ba68b5e97dad77d9b83795933575e3ad92ebe1961ba99f0decc7dca\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060408051808201825260088152672aa9a21021b7b4b760c11b6020808301918252835180850190945260048452635553444360e01b90840152815191929183918391620000629160039162000083565b5080516200007890600490602084019062000083565b505050505062000165565b828054620000919062000129565b90600052602060002090601f016020900481019282620000b5576000855562000100565b82601f10620000d057805160ff191683800117855562000100565b8280016001018555821562000100579182015b8281111562000100578251825591602001919060010190620000e3565b506200010e92915062000112565b5090565b5b808211156200010e576000815560010162000113565b600181811c908216806200013e57607f821691505b6020821081036200015f57634e487b7160e01b600052602260045260246000fd5b50919050565b610eba80620001756000396000f3fe6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023c578063a9059cbb1461025c578063dd62ed3e1461027c57600080fd5b80633ccfd60b146101dc57806370a08231146101f157806395d89b411461022757600080fd5b806323b872dd116100a557806323b872dd14610180578063313ce567146101a057806339509351146101bc57600080fd5b806306fdde0314610106578063095ea7b31461013157806318160ddd1461016157600080fd5b366101015760006100de60066012610b98565b6100e990600a610c9f565b6100f39034610cb5565b90506100ff33826102c2565b005b600080fd5b34801561011257600080fd5b5061011b6103a6565b6040516101289190610cd7565b60405180910390f35b34801561013d57600080fd5b5061015161014c366004610d48565b610438565b6040519015158152602001610128565b34801561016d57600080fd5b506002545b604051908152602001610128565b34801561018c57600080fd5b5061015161019b366004610d72565b61044f565b3480156101ac57600080fd5b5060405160068152602001610128565b3480156101c857600080fd5b506101516101d7366004610d48565b61050e565b3480156101e857600080fd5b506100ff61054a565b3480156101fd57600080fd5b5061017261020c366004610dae565b6001600160a01b031660009081526020819052604090205490565b34801561023357600080fd5b5061011b6105c0565b34801561024857600080fd5b50610151610257366004610d48565b6105cf565b34801561026857600080fd5b50610151610277366004610d48565b610680565b34801561028857600080fd5b50610172610297366004610dc9565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031d5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032f9190610dfc565b90915550506001600160a01b0382166000908152602081905260408120805483929061035c908490610dfc565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b590610e14565b80601f01602080910402602001604051908101604052809291908181526020018280546103e190610e14565b801561042e5780601f106104035761010080835404028352916020019161042e565b820191906000526020600020905b81548152906001019060200180831161041157829003601f168201915b5050505050905090565b600061044533848461068d565b5060015b92915050565b600061045c8484846107e5565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f65760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610314565b610503853385840361068d565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610445918590610545908690610dfc565b61068d565b336000818152602081905260409020549061056581836109fd565b6001600160a01b0381166108fc61057e60066012610b98565b61058990600a610c9f565b6105939085610e4e565b6040518115909202916000818181858888f193505050501580156105bb573d6000803e3d6000fd5b505050565b6060600480546103b590610e14565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106695760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610314565b610676338585840361068d565b5060019392505050565b60006104453384846107e5565b6001600160a01b0383166107085760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0382166107845760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166108615760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0382166108dd5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383166000908152602081905260409020548181101561096c5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a3908490610dfc565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ef91815260200190565b60405180910390a350505050565b6001600160a01b038216610a795760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b03821660009081526020819052604090205481811015610b085760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b37908490610e6d565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb257610bb2610b82565b90039392505050565b600181815b80851115610bf6578160001904821115610bdc57610bdc610b82565b80851615610be957918102915b93841c9390800290610bc0565b509250929050565b600082610c0d57506001610449565b81610c1a57506000610449565b8160018114610c305760028114610c3a57610c56565b6001915050610449565b60ff841115610c4b57610c4b610b82565b50506001821b610449565b5060208310610133831016604e8410600b8410161715610c79575081810a610449565b610c838383610bbb565b8060001904821115610c9757610c97610b82565b029392505050565b6000610cae60ff841683610bfe565b9392505050565b600082610cd257634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0457858101830151858201604001528201610ce8565b81811115610d16576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4357600080fd5b919050565b60008060408385031215610d5b57600080fd5b610d6483610d2c565b946020939093013593505050565b600080600060608486031215610d8757600080fd5b610d9084610d2c565b9250610d9e60208501610d2c565b9150604084013590509250925092565b600060208284031215610dc057600080fd5b610cae82610d2c565b60008060408385031215610ddc57600080fd5b610de583610d2c565b9150610df360208401610d2c565b90509250929050565b60008219821115610e0f57610e0f610b82565b500190565b600181811c90821680610e2857607f821691505b602082108103610e4857634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6857610e68610b82565b500290565b600082821015610e7f57610e7f610b82565b50039056fea26469706673582212207e0e9029f629065212929ea5e543fd08ff72836796ea1c16d1673e7b8d30365864736f6c634300080d0033", + "deployedBytecode": "0x6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023c578063a9059cbb1461025c578063dd62ed3e1461027c57600080fd5b80633ccfd60b146101dc57806370a08231146101f157806395d89b411461022757600080fd5b806323b872dd116100a557806323b872dd14610180578063313ce567146101a057806339509351146101bc57600080fd5b806306fdde0314610106578063095ea7b31461013157806318160ddd1461016157600080fd5b366101015760006100de60066012610b98565b6100e990600a610c9f565b6100f39034610cb5565b90506100ff33826102c2565b005b600080fd5b34801561011257600080fd5b5061011b6103a6565b6040516101289190610cd7565b60405180910390f35b34801561013d57600080fd5b5061015161014c366004610d48565b610438565b6040519015158152602001610128565b34801561016d57600080fd5b506002545b604051908152602001610128565b34801561018c57600080fd5b5061015161019b366004610d72565b61044f565b3480156101ac57600080fd5b5060405160068152602001610128565b3480156101c857600080fd5b506101516101d7366004610d48565b61050e565b3480156101e857600080fd5b506100ff61054a565b3480156101fd57600080fd5b5061017261020c366004610dae565b6001600160a01b031660009081526020819052604090205490565b34801561023357600080fd5b5061011b6105c0565b34801561024857600080fd5b50610151610257366004610d48565b6105cf565b34801561026857600080fd5b50610151610277366004610d48565b610680565b34801561028857600080fd5b50610172610297366004610dc9565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031d5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032f9190610dfc565b90915550506001600160a01b0382166000908152602081905260408120805483929061035c908490610dfc565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b590610e14565b80601f01602080910402602001604051908101604052809291908181526020018280546103e190610e14565b801561042e5780601f106104035761010080835404028352916020019161042e565b820191906000526020600020905b81548152906001019060200180831161041157829003601f168201915b5050505050905090565b600061044533848461068d565b5060015b92915050565b600061045c8484846107e5565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f65760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610314565b610503853385840361068d565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610445918590610545908690610dfc565b61068d565b336000818152602081905260409020549061056581836109fd565b6001600160a01b0381166108fc61057e60066012610b98565b61058990600a610c9f565b6105939085610e4e565b6040518115909202916000818181858888f193505050501580156105bb573d6000803e3d6000fd5b505050565b6060600480546103b590610e14565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106695760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610314565b610676338585840361068d565b5060019392505050565b60006104453384846107e5565b6001600160a01b0383166107085760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0382166107845760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166108615760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0382166108dd5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383166000908152602081905260409020548181101561096c5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a3908490610dfc565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ef91815260200190565b60405180910390a350505050565b6001600160a01b038216610a795760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b03821660009081526020819052604090205481811015610b085760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610314565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b37908490610e6d565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb257610bb2610b82565b90039392505050565b600181815b80851115610bf6578160001904821115610bdc57610bdc610b82565b80851615610be957918102915b93841c9390800290610bc0565b509250929050565b600082610c0d57506001610449565b81610c1a57506000610449565b8160018114610c305760028114610c3a57610c56565b6001915050610449565b60ff841115610c4b57610c4b610b82565b50506001821b610449565b5060208310610133831016604e8410600b8410161715610c79575081810a610449565b610c838383610bbb565b8060001904821115610c9757610c97610b82565b029392505050565b6000610cae60ff841683610bfe565b9392505050565b600082610cd257634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0457858101830151858201604001528201610ce8565b81811115610d16576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4357600080fd5b919050565b60008060408385031215610d5b57600080fd5b610d6483610d2c565b946020939093013593505050565b600080600060608486031215610d8757600080fd5b610d9084610d2c565b9250610d9e60208501610d2c565b9150604084013590509250925092565b600060208284031215610dc057600080fd5b610cae82610d2c565b60008060408385031215610ddc57600080fd5b610de583610d2c565b9150610df360208401610d2c565b90509250929050565b60008219821115610e0f57610e0f610b82565b500190565b600181811c90821680610e2857607f821691505b602082108103610e4857634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6857610e68610b82565b500290565b600082821015610e7f57610e7f610b82565b50039056fea26469706673582212207e0e9029f629065212929ea5e543fd08ff72836796ea1c16d1673e7b8d30365864736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 159, + "contract": "contracts/USDC.sol:USDC", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 165, + "contract": "contracts/USDC.sol:USDC", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 167, + "contract": "contracts/USDC.sol:USDC", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 169, + "contract": "contracts/USDC.sol:USDC", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 171, + "contract": "contracts/USDC.sol:USDC", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/arbitrum_goerli/WETH.json b/contracts/deployments/arbitrum_goerli/WETH.json new file mode 100644 index 00000000..b98e8d6e --- /dev/null +++ b/contracts/deployments/arbitrum_goerli/WETH.json @@ -0,0 +1,432 @@ +{ + "address": "0x4F1D9E040cf28A522ec79951cDb7B55c8aE4744E", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb42971d02b2163dd19deea52c74d424f7f57f65c9cd00e538620cdf58947af9e", + "receipt": { + "to": null, + "from": "0x902Fdb7c1EAbfcCB08321db1Fb5b54099a473CE1", + "contractAddress": "0x4F1D9E040cf28A522ec79951cDb7B55c8aE4744E", + "transactionIndex": 1, + "gasUsed": "914338", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x299372ef3f9d9dde14f60e19ed2a207020ed1d1ff925084934335536cf41b92a", + "transactionHash": "0xb42971d02b2163dd19deea52c74d424f7f57f65c9cd00e538620cdf58947af9e", + "logs": [], + "blockNumber": 2030829, + "cumulativeGasUsed": "914338", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3fcb829bdff3dbd1d10e0f68ff789618", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/WethToken.sol\":\"WETH\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\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\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/WethToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WrapToken.sol\\\";\\n\\ncontract WETH is WrapToken {\\n constructor() WrapToken(\\\"Wrapped Ether\\\", \\\"WETH\\\") {}\\n}\\n\",\"keccak256\":\"0xcb465eafb9c9dc0678b4b813bd91db8e6f98803fadaaaf22fb520b9ebc6a635d\",\"license\":\"GPL-3.0-or-later\"},\"contracts/WrapToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n//\\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\\n//\\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\\n\\npragma solidity ^0.8.0;\\n\\n// Learn more about the ERC20 implementation\\n// on OpenZeppelin docs: https://docs.openzeppelin.com/contracts/4.x/erc20\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n/// @notice This token is only intended to be used for testing.\\ncontract WrapToken is ERC20 {\\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\\n\\n /// @notice Allows minting tokens by sending Ether to it.\\n receive() external payable {\\n uint256 amount = msg.value / 10**(18 - decimals());\\n _mint(msg.sender, amount);\\n }\\n\\n function withdraw() external {\\n uint256 balance = balanceOf(msg.sender);\\n address payable sender = payable(msg.sender);\\n _burn(sender, balance);\\n sender.transfer(balance * 10**(18 - decimals()));\\n }\\n}\\n\",\"keccak256\":\"0x4562db1d9ba68b5e97dad77d9b83795933575e3ad92ebe1961ba99f0decc7dca\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252600d81526c2bb930b83832b21022ba3432b960991b6020808301918252835180850190945260048452630ae8aa8960e31b90840152815191929183918391620000679160039162000088565b5080516200007d90600490602084019062000088565b50505050506200016a565b82805462000096906200012e565b90600052602060002090601f016020900481019282620000ba576000855562000105565b82601f10620000d557805160ff191683800117855562000105565b8280016001018555821562000105579182015b8281111562000105578251825591602001919060010190620000e8565b506200011392915062000117565b5090565b5b8082111562000113576000815560010162000118565b600181811c908216806200014357607f821691505b6020821081036200016457634e487b7160e01b600052602260045260246000fd5b50919050565b610eb8806200017a6000396000f3fe6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023b578063a9059cbb1461025b578063dd62ed3e1461027b57600080fd5b80633ccfd60b146101db57806370a08231146101f057806395d89b411461022657600080fd5b806323b872dd116100a557806323b872dd1461017f578063313ce5671461019f57806339509351146101bb57600080fd5b806306fdde0314610105578063095ea7b31461013057806318160ddd1461016057600080fd5b366101005760006100dd601280610b96565b6100e890600a610c9d565b6100f29034610cb3565b90506100fe33826102c1565b005b600080fd5b34801561011157600080fd5b5061011a6103a5565b6040516101279190610cd5565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004610d46565b610437565b6040519015158152602001610127565b34801561016c57600080fd5b506002545b604051908152602001610127565b34801561018b57600080fd5b5061015061019a366004610d70565b61044e565b3480156101ab57600080fd5b5060405160128152602001610127565b3480156101c757600080fd5b506101506101d6366004610d46565b61050d565b3480156101e757600080fd5b506100fe610549565b3480156101fc57600080fd5b5061017161020b366004610dac565b6001600160a01b031660009081526020819052604090205490565b34801561023257600080fd5b5061011a6105be565b34801561024757600080fd5b50610150610256366004610d46565b6105cd565b34801561026757600080fd5b50610150610276366004610d46565b61067e565b34801561028757600080fd5b50610171610296366004610dc7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031c5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032e9190610dfa565b90915550506001600160a01b0382166000908152602081905260408120805483929061035b908490610dfa565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b490610e12565b80601f01602080910402602001604051908101604052809291908181526020018280546103e090610e12565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044433848461068b565b5060015b92915050565b600061045b8484846107e3565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f55760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610313565b610502853385840361068b565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610444918590610544908690610dfa565b61068b565b336000818152602081905260409020549061056481836109fb565b6001600160a01b0381166108fc61057c601280610b96565b61058790600a610c9d565b6105919085610e4c565b6040518115909202916000818181858888f193505050501580156105b9573d6000803e3d6000fd5b505050565b6060600480546103b490610e12565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106675760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610313565b610674338585840361068b565b5060019392505050565b60006104443384846107e3565b6001600160a01b0383166107065760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166107825760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661085f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166108db5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260409020548181101561096a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a1908490610dfa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ed91815260200190565b60405180910390a350505050565b6001600160a01b038216610a775760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b03821660009081526020819052604090205481811015610b065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b35908490610e6b565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb057610bb0610b80565b90039392505050565b600181815b80851115610bf4578160001904821115610bda57610bda610b80565b80851615610be757918102915b93841c9390800290610bbe565b509250929050565b600082610c0b57506001610448565b81610c1857506000610448565b8160018114610c2e5760028114610c3857610c54565b6001915050610448565b60ff841115610c4957610c49610b80565b50506001821b610448565b5060208310610133831016604e8410600b8410161715610c77575081810a610448565b610c818383610bb9565b8060001904821115610c9557610c95610b80565b029392505050565b6000610cac60ff841683610bfc565b9392505050565b600082610cd057634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0257858101830151858201604001528201610ce6565b81811115610d14576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4157600080fd5b919050565b60008060408385031215610d5957600080fd5b610d6283610d2a565b946020939093013593505050565b600080600060608486031215610d8557600080fd5b610d8e84610d2a565b9250610d9c60208501610d2a565b9150604084013590509250925092565b600060208284031215610dbe57600080fd5b610cac82610d2a565b60008060408385031215610dda57600080fd5b610de383610d2a565b9150610df160208401610d2a565b90509250929050565b60008219821115610e0d57610e0d610b80565b500190565b600181811c90821680610e2657607f821691505b602082108103610e4657634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6657610e66610b80565b500290565b600082821015610e7d57610e7d610b80565b50039056fea26469706673582212206b4d9a4936461552e3b25d8012a34303cf9102b5efc7c2666752f8ce336a7b9e64736f6c634300080d0033", + "deployedBytecode": "0x6080604052600436106100cb5760003560e01c80633ccfd60b11610074578063a457c2d71161004e578063a457c2d71461023b578063a9059cbb1461025b578063dd62ed3e1461027b57600080fd5b80633ccfd60b146101db57806370a08231146101f057806395d89b411461022657600080fd5b806323b872dd116100a557806323b872dd1461017f578063313ce5671461019f57806339509351146101bb57600080fd5b806306fdde0314610105578063095ea7b31461013057806318160ddd1461016057600080fd5b366101005760006100dd601280610b96565b6100e890600a610c9d565b6100f29034610cb3565b90506100fe33826102c1565b005b600080fd5b34801561011157600080fd5b5061011a6103a5565b6040516101279190610cd5565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004610d46565b610437565b6040519015158152602001610127565b34801561016c57600080fd5b506002545b604051908152602001610127565b34801561018b57600080fd5b5061015061019a366004610d70565b61044e565b3480156101ab57600080fd5b5060405160128152602001610127565b3480156101c757600080fd5b506101506101d6366004610d46565b61050d565b3480156101e757600080fd5b506100fe610549565b3480156101fc57600080fd5b5061017161020b366004610dac565b6001600160a01b031660009081526020819052604090205490565b34801561023257600080fd5b5061011a6105be565b34801561024757600080fd5b50610150610256366004610d46565b6105cd565b34801561026757600080fd5b50610150610276366004610d46565b61067e565b34801561028757600080fd5b50610171610296366004610dc7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03821661031c5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b806002600082825461032e9190610dfa565b90915550506001600160a01b0382166000908152602081905260408120805483929061035b908490610dfa565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060600380546103b490610e12565b80601f01602080910402602001604051908101604052809291908181526020018280546103e090610e12565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044433848461068b565b5060015b92915050565b600061045b8484846107e3565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104f55760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610313565b610502853385840361068b565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610444918590610544908690610dfa565b61068b565b336000818152602081905260409020549061056481836109fb565b6001600160a01b0381166108fc61057c601280610b96565b61058790600a610c9d565b6105919085610e4c565b6040518115909202916000818181858888f193505050501580156105b9573d6000803e3d6000fd5b505050565b6060600480546103b490610e12565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156106675760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610313565b610674338585840361068b565b5060019392505050565b60006104443384846107e3565b6001600160a01b0383166107065760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166107825760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661085f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0382166108db5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260409020548181101561096a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906109a1908490610dfa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109ed91815260200190565b60405180910390a350505050565b6001600160a01b038216610a775760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b03821660009081526020819052604090205481811015610b065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610313565b6001600160a01b0383166000908152602081905260408120838303905560028054849290610b35908490610e6b565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff841680821015610bb057610bb0610b80565b90039392505050565b600181815b80851115610bf4578160001904821115610bda57610bda610b80565b80851615610be757918102915b93841c9390800290610bbe565b509250929050565b600082610c0b57506001610448565b81610c1857506000610448565b8160018114610c2e5760028114610c3857610c54565b6001915050610448565b60ff841115610c4957610c49610b80565b50506001821b610448565b5060208310610133831016604e8410600b8410161715610c77575081810a610448565b610c818383610bb9565b8060001904821115610c9557610c95610b80565b029392505050565b6000610cac60ff841683610bfc565b9392505050565b600082610cd057634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610d0257858101830151858201604001528201610ce6565b81811115610d14576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610d4157600080fd5b919050565b60008060408385031215610d5957600080fd5b610d6283610d2a565b946020939093013593505050565b600080600060608486031215610d8557600080fd5b610d8e84610d2a565b9250610d9c60208501610d2a565b9150604084013590509250925092565b600060208284031215610dbe57600080fd5b610cac82610d2a565b60008060408385031215610dda57600080fd5b610de383610d2a565b9150610df160208401610d2a565b90509250929050565b60008219821115610e0d57610e0d610b80565b500190565b600181811c90821680610e2657607f821691505b602082108103610e4657634e487b7160e01b600052602260045260246000fd5b50919050565b6000816000190483118215151615610e6657610e66610b80565b500290565b600082821015610e7d57610e7d610b80565b50039056fea26469706673582212206b4d9a4936461552e3b25d8012a34303cf9102b5efc7c2666752f8ce336a7b9e64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. 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 value {ERC20} uses, unless this function is 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}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "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: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "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}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 159, + "contract": "contracts/WethToken.sol:WETH", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 165, + "contract": "contracts/WethToken.sol:WETH", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 167, + "contract": "contracts/WethToken.sol:WETH", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 169, + "contract": "contracts/WethToken.sol:WETH", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 171, + "contract": "contracts/WethToken.sol:WETH", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/contracts/deployments/arbitrum_goerli/solcInputs/3fcb829bdff3dbd1d10e0f68ff789618.json b/contracts/deployments/arbitrum_goerli/solcInputs/3fcb829bdff3dbd1d10e0f68ff789618.json new file mode 100644 index 00000000..7dad9fe7 --- /dev/null +++ b/contracts/deployments/arbitrum_goerli/solcInputs/3fcb829bdff3dbd1d10e0f68ff789618.json @@ -0,0 +1,188 @@ +{ + "language": "Solidity", + "sources": { + "contracts/AssetRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./libraries/BN254.sol\";\nimport \"./libraries/EdOnBN254.sol\";\n\ncontract AssetRegistry {\n bytes13 public constant DOM_SEP_FOREIGN_ASSET = \"FOREIGN_ASSET\";\n bytes14 public constant DOM_SEP_DOMESTIC_ASSET = \"DOMESTIC_ASSET\";\n uint256 public constant CAP_NATIVE_ASSET_CODE = 1;\n\n event AssetSponsored(address erc20Address, uint256 assetDefinitionCode);\n\n mapping(bytes32 => address) public assets;\n\n struct AssetDefinition {\n uint256 code;\n AssetPolicy policy;\n }\n\n struct AssetPolicy {\n EdOnBN254.EdOnBN254Point auditorPk;\n EdOnBN254.EdOnBN254Point credPk;\n EdOnBN254.EdOnBN254Point freezerPk;\n uint256 revealMap;\n uint128 revealThreshold;\n }\n\n /// @notice Return the CAP-native asset definition.\n function nativeDomesticAsset() public pure returns (AssetDefinition memory assetDefinition) {\n assetDefinition.code = CAP_NATIVE_ASSET_CODE;\n // affine representation of zero point in arkwork is (0,1)\n assetDefinition.policy.auditorPk.y = 1;\n assetDefinition.policy.credPk.y = 1;\n assetDefinition.policy.freezerPk.y = 1;\n }\n\n /// @notice Fetch the ERC-20 token address corresponding to the\n /// given asset definition.\n /// @param assetDefinition an asset definition\n /// @return An ERC-20 address\n function lookup(AssetDefinition memory assetDefinition) public view returns (address) {\n bytes32 key = keccak256(abi.encode(assetDefinition));\n return assets[key];\n }\n\n /// @notice Is the given asset definition registered?\n /// @param assetDefinition an asset definition\n /// @return True if the asset type is registered, false otherwise.\n function isCapeAssetRegistered(AssetDefinition memory assetDefinition)\n public\n view\n returns (bool)\n {\n return lookup(assetDefinition) != address(0);\n }\n\n /// @notice Create and register a new asset type associated with an\n /// ERC-20 token. Will revert if the asset type is already\n /// registered or the ERC-20 token address is zero.\n /// @param erc20Address An ERC-20 token address\n /// @param newAsset An asset type to be registered in the contract\n function sponsorCapeAsset(address erc20Address, AssetDefinition memory newAsset) external {\n require(erc20Address != address(0), \"Bad asset address\");\n require(!isCapeAssetRegistered(newAsset), \"Asset already registered\");\n\n _checkForeignAssetCode(newAsset.code, erc20Address, msg.sender, newAsset.policy);\n\n bytes32 key = keccak256(abi.encode(newAsset));\n assets[key] = erc20Address;\n\n emit AssetSponsored(erc20Address, newAsset.code);\n }\n\n /// @notice Throws an exception if the asset definition code is\n /// not correctly derived from the ERC-20 address of the token and\n /// the address of the sponsor.\n /// @dev Requires \"view\" to access msg.sender.\n /// @param assetDefinitionCode The code of an asset definition\n /// @param erc20Address The ERC-20 address bound to the asset definition\n /// @param sponsor The sponsor address of this wrapped asset\n /// @param policy asset policy\n function _checkForeignAssetCode(\n uint256 assetDefinitionCode,\n address erc20Address,\n address sponsor,\n AssetPolicy memory policy\n ) internal pure {\n bytes memory description = _computeAssetDescription(erc20Address, sponsor, policy);\n require(\n assetDefinitionCode ==\n BN254.fromLeBytesModOrder(\n bytes.concat(keccak256(bytes.concat(DOM_SEP_FOREIGN_ASSET, description)))\n ),\n \"Wrong foreign asset code\"\n );\n }\n\n /// @dev Checks if the asset definition code is correctly derived from the internal asset code.\n /// @param assetDefinitionCode asset definition code\n /// @param internalAssetCode internal asset code\n function _checkDomesticAssetCode(uint256 assetDefinitionCode, uint256 internalAssetCode)\n internal\n pure\n {\n require(\n assetDefinitionCode ==\n BN254.fromLeBytesModOrder(\n bytes.concat(\n keccak256(\n bytes.concat(\n DOM_SEP_DOMESTIC_ASSET,\n bytes32(Utils.reverseEndianness(internalAssetCode))\n )\n )\n )\n ),\n \"Wrong domestic asset code\"\n );\n }\n\n /// @dev Compute the asset description from the address of the\n /// ERC-20 token and the address of the sponsor.\n /// @param erc20Address address of the erc20 token\n /// @param sponsor address of the sponsor\n /// @param policy asset policy\n /// @return The asset description\n function _computeAssetDescription(\n address erc20Address,\n address sponsor,\n AssetPolicy memory policy\n ) internal pure returns (bytes memory) {\n return\n bytes.concat(\n \"EsSCAPE ERC20\",\n bytes20(erc20Address),\n \"sponsored by\",\n bytes20(sponsor),\n \"policy\",\n abi.encode(policy)\n );\n }\n}\n" + }, + "contracts/libraries/BN254.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n//\n// Based on:\n// - Christian Reitwiessner: https://gist.githubusercontent.com/chriseth/f9be9d9391efc5beb9704255a8e2989d/raw/4d0fb90847df1d4e04d507019031888df8372239/snarktest.solidity\n// - Aztec: https://github.com/AztecProtocol/aztec-2-bug-bounty\n\npragma solidity ^0.8.0;\n\nimport \"./Utils.sol\";\n\n/// @notice Barreto-Naehrig curve over a 254 bit prime field\nlibrary BN254 {\n // use notation from https://datatracker.ietf.org/doc/draft-irtf-cfrg-pairing-friendly-curves/\n //\n // Elliptic curve is defined over a prime field GF(p), with embedding degree k.\n // Short Weierstrass (SW form) is, for a, b \\in GF(p^n) for some natural number n > 0:\n // E: y^2 = x^3 + a * x + b\n //\n // Pairing is defined over cyclic subgroups G1, G2, both of which are of order r.\n // G1 is a subgroup of E(GF(p)), G2 is a subgroup of E(GF(p^k)).\n //\n // BN family are parameterized curves with well-chosen t,\n // p = 36 * t^4 + 36 * t^3 + 24 * t^2 + 6 * t + 1\n // r = 36 * t^4 + 36 * t^3 + 18 * t^2 + 6 * t + 1\n // for some integer t.\n // E has the equation:\n // E: y^2 = x^3 + b\n // where b is a primitive element of multiplicative group (GF(p))^* of order (p-1).\n // A pairing e is defined by taking G1 as a subgroup of E(GF(p)) of order r,\n // G2 as a subgroup of E'(GF(p^2)),\n // and G_T as a subgroup of a multiplicative group (GF(p^12))^* of order r.\n //\n // BN254 is defined over a 254-bit prime order p, embedding degree k = 12.\n uint256 public constant P_MOD =\n 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n uint256 public constant R_MOD =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n // G2 group element where x \\in Fp2 = x0 * z + x1\n struct G2Point {\n uint256 x0;\n uint256 x1;\n uint256 y0;\n uint256 y1;\n }\n\n /// @return the generator of G1\n // solhint-disable-next-line func-name-mixedcase\n function P1() internal pure returns (G1Point memory) {\n return G1Point(1, 2);\n }\n\n /// @return the generator of G2\n // solhint-disable-next-line func-name-mixedcase\n function P2() internal pure returns (G2Point memory) {\n return\n G2Point({\n x0: 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2,\n x1: 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed,\n y0: 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b,\n y1: 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\n });\n }\n\n /// @dev check if a G1 point is Infinity\n /// @notice precompile bn256Add at address(6) takes (0, 0) as Point of Infinity,\n /// some crypto libraries (such as arkwork) uses a boolean flag to mark PoI, and\n /// just use (0, 1) as affine coordinates (not on curve) to represents PoI.\n function isInfinity(G1Point memory point) internal pure returns (bool result) {\n assembly {\n let x := mload(point)\n let y := mload(add(point, 0x20))\n result := and(iszero(x), iszero(y))\n }\n }\n\n /// @return r the negation of p, i.e. p.add(p.negate()) should be zero.\n function negate(G1Point memory p) internal pure returns (G1Point memory) {\n if (isInfinity(p)) {\n return p;\n }\n return G1Point(p.x, P_MOD - (p.y % P_MOD));\n }\n\n /// @return res = -fr the negation of scalar field element.\n function negate(uint256 fr) internal pure returns (uint256 res) {\n return R_MOD - (fr % R_MOD);\n }\n\n /// @return r the sum of two points of G1\n function add(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\n uint256[4] memory input;\n input[0] = p1.x;\n input[1] = p1.y;\n input[2] = p2.x;\n input[3] = p2.y;\n bool success;\n assembly {\n success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 {\n revert(0, 0)\n }\n }\n require(success, \"Bn254: group addition failed!\");\n }\n\n /// @return r the product of a point on G1 and a scalar, i.e.\n /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n function scalarMul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\n uint256[3] memory input;\n input[0] = p.x;\n input[1] = p.y;\n input[2] = s;\n bool success;\n assembly {\n success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 {\n revert(0, 0)\n }\n }\n require(success, \"Bn254: scalar mul failed!\");\n }\n\n /// @dev Multi-scalar Mulitiplication (MSM)\n /// @return r = \\Prod{B_i^s_i} where {s_i} are `scalars` and {B_i} are `bases`\n function multiScalarMul(G1Point[] memory bases, uint256[] memory scalars)\n internal\n view\n returns (G1Point memory r)\n {\n require(scalars.length == bases.length, \"MSM error: length does not match\");\n\n r = scalarMul(bases[0], scalars[0]);\n for (uint256 i = 1; i < scalars.length; i++) {\n r = add(r, scalarMul(bases[i], scalars[i]));\n }\n }\n\n /// @dev Compute f^-1 for f \\in Fr scalar field\n /// @notice credit: Aztec, Spilsbury Holdings Ltd\n function invert(uint256 fr) internal view returns (uint256 output) {\n bool success;\n uint256 p = R_MOD;\n assembly {\n let mPtr := mload(0x40)\n mstore(mPtr, 0x20)\n mstore(add(mPtr, 0x20), 0x20)\n mstore(add(mPtr, 0x40), 0x20)\n mstore(add(mPtr, 0x60), fr)\n mstore(add(mPtr, 0x80), sub(p, 2))\n mstore(add(mPtr, 0xa0), p)\n success := staticcall(gas(), 0x05, mPtr, 0xc0, 0x00, 0x20)\n output := mload(0x00)\n }\n require(success, \"Bn254: pow precompile failed!\");\n }\n\n /**\n * validate the following:\n * x != 0\n * y != 0\n * x < p\n * y < p\n * y^2 = x^3 + 3 mod p\n */\n /// @dev validate G1 point and check if it is on curve\n /// @notice credit: Aztec, Spilsbury Holdings Ltd\n function validateG1Point(G1Point memory point) internal pure {\n bool isWellFormed;\n uint256 p = P_MOD;\n assembly {\n let x := mload(point)\n let y := mload(add(point, 0x20))\n\n isWellFormed := and(\n and(and(lt(x, p), lt(y, p)), not(or(iszero(x), iszero(y)))),\n eq(mulmod(y, y, p), addmod(mulmod(x, mulmod(x, x, p), p), 3, p))\n )\n }\n require(isWellFormed, \"Bn254: invalid G1 point\");\n }\n\n /// @dev Validate scalar field, revert if invalid (namely if fr > r_mod).\n /// @notice Writing this inline instead of calling it might save gas.\n function validateScalarField(uint256 fr) internal pure {\n bool isValid;\n assembly {\n isValid := lt(fr, R_MOD)\n }\n require(isValid, \"Bn254: invalid scalar field\");\n }\n\n /// @dev Evaluate the following pairing product:\n /// @dev e(a1, a2).e(-b1, b2) == 1\n /// @dev caller needs to ensure that a1, a2, b1 and b2 are within proper group\n /// @notice credit: Aztec, Spilsbury Holdings Ltd\n function pairingProd2(\n G1Point memory a1,\n G2Point memory a2,\n G1Point memory b1,\n G2Point memory b2\n ) internal view returns (bool) {\n uint256 out;\n bool success;\n assembly {\n let mPtr := mload(0x40)\n mstore(mPtr, mload(a1))\n mstore(add(mPtr, 0x20), mload(add(a1, 0x20)))\n mstore(add(mPtr, 0x40), mload(a2))\n mstore(add(mPtr, 0x60), mload(add(a2, 0x20)))\n mstore(add(mPtr, 0x80), mload(add(a2, 0x40)))\n mstore(add(mPtr, 0xa0), mload(add(a2, 0x60)))\n\n mstore(add(mPtr, 0xc0), mload(b1))\n mstore(add(mPtr, 0xe0), mload(add(b1, 0x20)))\n mstore(add(mPtr, 0x100), mload(b2))\n mstore(add(mPtr, 0x120), mload(add(b2, 0x20)))\n mstore(add(mPtr, 0x140), mload(add(b2, 0x40)))\n mstore(add(mPtr, 0x160), mload(add(b2, 0x60)))\n success := staticcall(gas(), 8, mPtr, 0x180, 0x00, 0x20)\n out := mload(0x00)\n }\n require(success, \"Bn254: Pairing check failed!\");\n return (out != 0);\n }\n\n function fromLeBytesModOrder(bytes memory leBytes) internal pure returns (uint256 ret) {\n for (uint256 i = 0; i < leBytes.length; i++) {\n ret = mulmod(ret, 256, R_MOD);\n ret = addmod(ret, uint256(uint8(leBytes[leBytes.length - 1 - i])), R_MOD);\n }\n }\n\n /// @dev Check if y-coordinate of G1 point is negative.\n function isYNegative(G1Point memory point) internal pure returns (bool) {\n return (point.y << 1) < P_MOD;\n }\n\n // @dev Perform a modular exponentiation.\n // @return base^exponent (mod modulus)\n // This method is ideal for small exponents (~64 bits or less), as it is cheaper than using the pow precompile\n // @notice credit: credit: Aztec, Spilsbury Holdings Ltd\n function powSmall(\n uint256 base,\n uint256 exponent,\n uint256 modulus\n ) internal pure returns (uint256) {\n uint256 result = 1;\n uint256 input = base;\n uint256 count = 1;\n\n assembly {\n let endpoint := add(exponent, 0x01)\n for {\n\n } lt(count, endpoint) {\n count := add(count, count)\n } {\n if and(exponent, count) {\n result := mulmod(result, input, modulus)\n }\n input := mulmod(input, input, modulus)\n }\n }\n\n return result;\n }\n\n function g1Serialize(G1Point memory point) internal pure returns (bytes memory) {\n uint256 mask = 0;\n\n // Set the 254-th bit to 1 for infinity\n // https://docs.rs/ark-serialize/0.3.0/src/ark_serialize/flags.rs.html#117\n if (isInfinity(point)) {\n mask |= 0x4000000000000000000000000000000000000000000000000000000000000000;\n }\n\n // Set the 255-th bit to 1 for positive Y\n // https://docs.rs/ark-serialize/0.3.0/src/ark_serialize/flags.rs.html#118\n if (!isYNegative(point)) {\n mask = 0x8000000000000000000000000000000000000000000000000000000000000000;\n }\n\n return abi.encodePacked(Utils.reverseEndianness(point.x | mask));\n }\n\n function g1Deserialize(bytes32 input) internal view returns (G1Point memory point) {\n uint256 mask = 0x4000000000000000000000000000000000000000000000000000000000000000;\n uint256 x = Utils.reverseEndianness(uint256(input));\n uint256 y;\n bool isQuadraticResidue;\n bool isYPositive;\n if (x & mask != 0) {\n // the 254-th bit == 1 for infinity\n x = 0;\n y = 0;\n } else {\n // Set the 255-th bit to 1 for positive Y\n mask = 0x8000000000000000000000000000000000000000000000000000000000000000;\n isYPositive = (x & mask != 0);\n // mask off the first two bits of x\n mask = 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n x &= mask;\n\n // solve for y where E: y^2 = x^3 + 3\n y = mulmod(x, x, P_MOD);\n y = mulmod(y, x, P_MOD);\n y = addmod(y, 3, P_MOD);\n (isQuadraticResidue, y) = quadraticResidue(y);\n\n require(isQuadraticResidue, \"deser fail: not on curve\");\n\n if (isYPositive) {\n y = P_MOD - y;\n }\n }\n\n point = G1Point(x, y);\n }\n\n function quadraticResidue(uint256 x)\n internal\n view\n returns (bool isQuadraticResidue, uint256 a)\n {\n bool success;\n // e = (p+1)/4\n uint256 e = 0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52;\n uint256 p = P_MOD;\n\n // we have p == 3 mod 4 therefore\n // a = x^((p+1)/4)\n assembly {\n // credit: Aztec\n let mPtr := mload(0x40)\n mstore(mPtr, 0x20)\n mstore(add(mPtr, 0x20), 0x20)\n mstore(add(mPtr, 0x40), 0x20)\n mstore(add(mPtr, 0x60), x)\n mstore(add(mPtr, 0x80), e)\n mstore(add(mPtr, 0xa0), p)\n success := staticcall(gas(), 0x05, mPtr, 0xc0, 0x00, 0x20)\n a := mload(0x00)\n }\n require(success, \"pow precompile call failed!\");\n\n // ensure a < p/2\n if (a << 1 > p) {\n a = p - a;\n }\n\n // check if a^2 = x, if not x is not a quadratic residue\n e = mulmod(a, a, p);\n\n isQuadraticResidue = (e == x);\n }\n}\n" + }, + "contracts/libraries/EdOnBN254.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../libraries/Utils.sol\";\n\n/// @notice Edward curve on BN254.\n/// This library only implements a serialization function that is consistent with\n/// Arkworks' format. It does not support any group operations.\nlibrary EdOnBN254 {\n uint256 public constant P_MOD =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n struct EdOnBN254Point {\n uint256 x;\n uint256 y;\n }\n\n /// @dev Check if y-coordinate of G1 point is negative.\n function isYNegative(EdOnBN254Point memory point) internal pure returns (bool) {\n return (point.y << 1) < P_MOD;\n }\n\n function serialize(EdOnBN254Point memory point) internal pure returns (bytes memory res) {\n uint256 mask = 0;\n // Edward curve does not have an infinity flag.\n // Set the 255-th bit to 1 for positive Y\n // See: https://github.com/arkworks-rs/algebra/blob/d6365c3a0724e5d71322fe19cbdb30f979b064c8/serialize/src/flags.rs#L148\n if (!EdOnBN254.isYNegative(point)) {\n mask = 0x8000000000000000000000000000000000000000000000000000000000000000;\n }\n\n return abi.encodePacked(Utils.reverseEndianness(point.x | mask));\n }\n}\n" + }, + "contracts/libraries/Utils.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nlibrary Utils {\n function reverseEndianness(uint256 input) internal pure returns (uint256 v) {\n v = input;\n\n // swap bytes\n v =\n ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |\n ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n\n // swap 2-byte long pairs\n v =\n ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |\n ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n\n // swap 4-byte long pairs\n v =\n ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |\n ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);\n\n // swap 8-byte long pairs\n v =\n ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |\n ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);\n\n // swap 16-byte long pairs\n v = (v >> 128) | (v << 128);\n }\n}\n" + }, + "contracts/CAPE.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\n/// @title Configurable Anonymous Payments for Ethereum\n/// CAPE provides auditable anonymous payments on Ethereum.\n/// @author Espresso Systems \n\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport \"@rari-capital/solmate/src/utils/SafeTransferLib.sol\";\n\nimport \"solidity-bytes-utils/contracts/BytesLib.sol\";\nimport \"./libraries/AccumulatingArray.sol\";\nimport \"./libraries/EdOnBN254.sol\";\nimport \"./libraries/RescueLib.sol\";\nimport \"./libraries/VerifyingKeys.sol\";\nimport \"./interfaces/IPlonkVerifier.sol\";\nimport \"./interfaces/IRecordsMerkleTree.sol\";\nimport \"./AssetRegistry.sol\";\nimport \"./RootStore.sol\";\n\ncontract CAPE is RootStore, AssetRegistry, ReentrancyGuard {\n using AccumulatingArray for AccumulatingArray.Data;\n\n mapping(uint256 => bool) public nullifiers;\n uint64 public blockHeight;\n IPlonkVerifier private _verifier;\n IRecordsMerkleTree internal _recordsMerkleTree;\n uint256[] public pendingDeposits;\n\n // NOTE: used for faucet in testnet only, will be removed for mainnet\n address public deployer;\n bool public faucetInitialized;\n\n bytes public constant CAPE_BURN_MAGIC_BYTES = \"EsSCAPE burn\";\n uint256 public constant CAPE_BURN_MAGIC_BYTES_SIZE = 12;\n // In order to avoid the contract running out of gas if the queue is too large\n // we set the maximum number of pending deposits record commitments to process\n // when a new block is submitted. This is a temporary solution.\n // See https://github.com/EspressoSystems/cape/issues/400\n uint256 public constant MAX_NUM_PENDING_DEPOSIT = 10;\n\n event FaucetInitialized(bytes roBytes);\n\n event BlockCommitted(\n uint64 indexed height,\n uint256[] depositCommitments,\n // What follows is a `CapeBlock` struct split up into fields.\n // This may no longer be necessary once\n // https://github.com/gakonst/ethers-rs/issues/1220\n // is fixed.\n bytes minerAddr,\n bytes noteTypes,\n bytes transferNotes,\n bytes mintNotes,\n bytes freezeNotes,\n bytes burnNotes\n );\n\n event Erc20TokensDeposited(bytes roBytes, address erc20TokenAddress, address from);\n\n struct AuditMemo {\n EdOnBN254.EdOnBN254Point ephemeralKey;\n uint256[] data;\n }\n\n enum NoteType {\n TRANSFER,\n MINT,\n FREEZE,\n BURN\n }\n\n struct TransferNote {\n uint256[] inputNullifiers;\n uint256[] outputCommitments;\n IPlonkVerifier.PlonkProof proof;\n AuditMemo auditMemo;\n TransferAuxInfo auxInfo;\n }\n\n struct BurnNote {\n TransferNote transferNote;\n RecordOpening recordOpening;\n }\n\n struct MintNote {\n /// nullifier for the input (i.e. transaction fee record)\n uint256 inputNullifier;\n /// output commitment for the fee change\n uint256 chgComm;\n /// output commitment for the minted asset\n uint256 mintComm;\n /// the amount of the minted asset\n uint128 mintAmount;\n /// the asset definition of the asset\n AssetDefinition mintAssetDef;\n /// Internal asset code\n uint256 mintInternalAssetCode;\n /// the validity proof of this note\n IPlonkVerifier.PlonkProof proof;\n /// memo for policy compliance specified for the designated auditor\n AuditMemo auditMemo;\n /// auxiliary information\n MintAuxInfo auxInfo;\n }\n\n struct FreezeNote {\n uint256[] inputNullifiers;\n uint256[] outputCommitments;\n IPlonkVerifier.PlonkProof proof;\n FreezeAuxInfo auxInfo;\n }\n\n struct TransferAuxInfo {\n uint256 merkleRoot;\n uint128 fee;\n uint64 validUntil;\n EdOnBN254.EdOnBN254Point txnMemoVerKey;\n bytes extraProofBoundData;\n }\n\n struct MintAuxInfo {\n uint256 merkleRoot;\n uint128 fee;\n EdOnBN254.EdOnBN254Point txnMemoVerKey;\n }\n\n struct FreezeAuxInfo {\n uint256 merkleRoot;\n uint128 fee;\n EdOnBN254.EdOnBN254Point txnMemoVerKey;\n }\n\n struct RecordOpening {\n uint128 amount;\n AssetDefinition assetDef;\n EdOnBN254.EdOnBN254Point userAddr;\n bytes32 encKey;\n bool freezeFlag;\n uint256 blind;\n }\n\n struct CapeBlock {\n EdOnBN254.EdOnBN254Point minerAddr;\n NoteType[] noteTypes;\n TransferNote[] transferNotes;\n MintNote[] mintNotes;\n FreezeNote[] freezeNotes;\n BurnNote[] burnNotes;\n }\n\n /// @notice CAPE contract constructor method.\n /// @param nRoots number of the most recent roots of the records merkle tree to be stored\n /// @param verifierAddr address of the Plonk Verifier contract\n constructor(\n uint64 nRoots,\n address verifierAddr,\n address recordsMerkleTreeAddr\n ) RootStore(nRoots) {\n _verifier = IPlonkVerifier(verifierAddr);\n _recordsMerkleTree = IRecordsMerkleTree(recordsMerkleTreeAddr);\n\n // NOTE: used for faucet in testnet only, will be removed for mainnet\n deployer = msg.sender;\n }\n\n /// @notice Allocate native token faucet to a manager. For testnet only.\n /// @param faucetManagerAddress address of public key of faucet manager for CAP native token (testnet only!)\n /// @param faucetManagerEncKey public key of faucet manager for CAP native token (testnet only!)\n function faucetSetupForTestnet(\n EdOnBN254.EdOnBN254Point memory faucetManagerAddress,\n bytes32 faucetManagerEncKey\n ) external {\n // faucet can only be set up once by the manager\n require(msg.sender == deployer, \"Only invocable by deployer\");\n require(!faucetInitialized, \"Faucet already set up\");\n\n // allocate maximum possible amount of native CAP token to faucet manager on testnet\n // max amount len is set to 63 bits: https://github.com/EspressoSystems/cap/blob/main/src/constants.rs#L50-L51\n RecordOpening memory ro = RecordOpening(\n type(uint128).max / 2,\n nativeDomesticAsset(),\n faucetManagerAddress,\n faucetManagerEncKey,\n false,\n 0 // arbitrary blind factor\n );\n uint256[] memory recordCommitments = new uint256[](1);\n recordCommitments[0] = _deriveRecordCommitment(ro);\n\n // Insert the record into record accumulator.\n //\n // This is a call to our own contract, not an arbitrary external contract.\n // slither-disable-next-line reentrancy-no-eth\n _recordsMerkleTree.updateRecordsMerkleTree(recordCommitments);\n // slither-disable-next-line reentrancy-benign\n _addRoot(_recordsMerkleTree.getRootValue());\n\n // slither-disable-next-line reentrancy-events\n emit FaucetInitialized(abi.encode(ro));\n faucetInitialized = true;\n }\n\n /// @notice Publish an array of nullifiers.\n /// @dev Requires all nullifiers to be unique and unpublished.\n /// @dev A block creator must not submit notes with duplicate nullifiers.\n /// @param newNullifiers list of nullifiers to publish\n function _publish(uint256[] memory newNullifiers) internal {\n for (uint256 j = 0; j < newNullifiers.length; j++) {\n _publish(newNullifiers[j]);\n }\n }\n\n /// @notice Publish a nullifier if it hasn't been published before.\n /// @dev Reverts if the nullifier is already published.\n /// @param nullifier nullifier to publish\n function _publish(uint256 nullifier) internal {\n require(!nullifiers[nullifier], \"Nullifier already published\");\n nullifiers[nullifier] = true;\n }\n\n /// @notice Wraps ERC-20 tokens into a CAPE asset defined in the record opening.\n /// @param ro record opening that will be inserted in the records merkle tree once the deposit is validated\n /// @param erc20Address address of the ERC-20 token corresponding to the deposit\n function depositErc20(RecordOpening memory ro, address erc20Address) external nonReentrant {\n require(isCapeAssetRegistered(ro.assetDef), \"Asset definition not registered\");\n require(lookup(ro.assetDef) == erc20Address, \"Wrong ERC20 address\");\n\n // We skip the sanity checks mentioned in the rust specification as they are optional.\n if (pendingDeposits.length >= MAX_NUM_PENDING_DEPOSIT) {\n revert(\"Pending deposits queue is full\");\n }\n pendingDeposits.push(_deriveRecordCommitment(ro));\n\n SafeTransferLib.safeTransferFrom(\n ERC20(erc20Address),\n msg.sender,\n address(this),\n ro.amount\n );\n\n emit Erc20TokensDeposited(abi.encode(ro), erc20Address, msg.sender);\n }\n\n /// @notice Submit a new block with extra data to the CAPE contract.\n /// @param newBlock block to be processed by the CAPE contract\n /// @param {bytes} extraData data to be stored in calldata; this data is ignored by the contract function\n function submitCapeBlockWithMemos(\n CapeBlock memory newBlock,\n bytes calldata /* extraData */\n ) external {\n submitCapeBlock(newBlock);\n }\n\n /// @notice Submit a new block to the CAPE contract.\n /// @dev Transactions are validated and the blockchain state is updated. Moreover *BURN* transactions trigger the unwrapping of cape asset records into erc20 tokens.\n /// @param newBlock block to be processed by the CAPE contract.\n function submitCapeBlock(CapeBlock memory newBlock) public nonReentrant {\n AccumulatingArray.Data memory commitments = AccumulatingArray.create(\n _computeNumCommitments(newBlock) + pendingDeposits.length\n );\n\n uint256 numNotes = newBlock.noteTypes.length;\n\n // Batch verify plonk proofs\n IPlonkVerifier.VerifyingKey[] memory vks = new IPlonkVerifier.VerifyingKey[](numNotes);\n uint256[][] memory publicInputs = new uint256[][](numNotes);\n IPlonkVerifier.PlonkProof[] memory proofs = new IPlonkVerifier.PlonkProof[](numNotes);\n bytes[] memory extraMsgs = new bytes[](numNotes);\n\n // Preserve the ordering of the (sub) arrays of notes.\n uint256 transferIdx = 0;\n uint256 mintIdx = 0;\n uint256 freezeIdx = 0;\n uint256 burnIdx = 0;\n\n // We require either the block or the pending deposits queue to be non empty. That is we expect the block submission to trigger some change in the blockchain state.\n // The reason is that, due to race conditions, it is possible to have the relayer send an empty block while the pending deposits queue is still empty.\n // If we do not reject the block, the `blockHeight` contract variable will be incremented, yet the set of records merkle tree roots will be unchanged.\n // On the other side, the wallet assumes that the blockHeight is equal to the number of roots and thus, in the case of a block submission that only increments `blockHeight`,\n // the wallet and the contract states become inconsistent.\n require(!((numNotes == 0) && (pendingDeposits.length == 0)), \"Block must be non-empty\");\n\n for (uint256 i = 0; i < numNotes; i++) {\n NoteType noteType = newBlock.noteTypes[i];\n\n if (noteType == NoteType.TRANSFER) {\n TransferNote memory note = newBlock.transferNotes[transferIdx];\n transferIdx += 1;\n\n _checkContainsRoot(note.auxInfo.merkleRoot);\n _checkTransfer(note);\n require(!_isExpired(note), \"Expired note\");\n\n _publish(note.inputNullifiers);\n\n commitments.add(note.outputCommitments);\n\n (vks[i], publicInputs[i], proofs[i], extraMsgs[i]) = _prepareForProofVerification(\n note\n );\n } else if (noteType == NoteType.MINT) {\n MintNote memory note = newBlock.mintNotes[mintIdx];\n mintIdx += 1;\n\n _checkContainsRoot(note.auxInfo.merkleRoot);\n _checkDomesticAssetCode(note.mintAssetDef.code, note.mintInternalAssetCode);\n\n _publish(note.inputNullifier);\n\n commitments.add(note.chgComm);\n commitments.add(note.mintComm);\n\n (vks[i], publicInputs[i], proofs[i], extraMsgs[i]) = _prepareForProofVerification(\n note\n );\n } else if (noteType == NoteType.FREEZE) {\n FreezeNote memory note = newBlock.freezeNotes[freezeIdx];\n freezeIdx += 1;\n\n _checkContainsRoot(note.auxInfo.merkleRoot);\n\n _publish(note.inputNullifiers);\n\n commitments.add(note.outputCommitments);\n\n (vks[i], publicInputs[i], proofs[i], extraMsgs[i]) = _prepareForProofVerification(\n note\n );\n } else if (noteType == NoteType.BURN) {\n BurnNote memory note = newBlock.burnNotes[burnIdx];\n burnIdx += 1;\n\n _checkContainsRoot(note.transferNote.auxInfo.merkleRoot);\n _checkBurn(note);\n\n _publish(note.transferNote.inputNullifiers);\n\n // Insert all the output commitments to the records merkle tree except from the second one (corresponding to the burned output)\n for (uint256 j = 0; j < note.transferNote.outputCommitments.length; j++) {\n if (j != 1) {\n commitments.add(note.transferNote.outputCommitments[j]);\n }\n }\n\n (vks[i], publicInputs[i], proofs[i], extraMsgs[i]) = _prepareForProofVerification(\n note\n );\n\n // Send the tokens\n _handleWithdrawal(note);\n } else {\n revert(\"Cape: unreachable!\");\n }\n }\n\n // Skip the batch plonk verification if the block is empty\n if (numNotes > 0) {\n require(\n _verifier.batchVerify(vks, publicInputs, proofs, extraMsgs),\n \"Cape: batch verify failed.\"\n );\n }\n\n // Process the pending deposits obtained after calling `depositErc20`\n for (uint256 i = 0; i < pendingDeposits.length; i++) {\n commitments.add(pendingDeposits[i]);\n }\n\n // Only update the merkle tree and add the root if the list of records commitments is non empty\n if (!commitments.isEmpty()) {\n // This is a call to our own contract, not an arbitrary external contract.\n // slither-disable-next-line reentrancy-no-eth\n _recordsMerkleTree.updateRecordsMerkleTree(commitments.items);\n // slither-disable-next-line reentrancy-benign\n _addRoot(_recordsMerkleTree.getRootValue());\n }\n\n // In all cases (the block is empty or not), the height is incremented.\n blockHeight += 1;\n\n // Inform clients about the new block and the processed deposits.\n // slither-disable-next-line reentrancy-events\n _emitBlockEvent(newBlock);\n\n // Empty the queue now that the record commitments have been inserted\n delete pendingDeposits;\n }\n\n /// @notice This function only exists to avoid a stack too deep compilation error.\n function _emitBlockEvent(CapeBlock memory newBlock) internal {\n emit BlockCommitted(\n blockHeight,\n pendingDeposits,\n abi.encode(newBlock.minerAddr),\n abi.encode(newBlock.noteTypes),\n abi.encode(newBlock.transferNotes),\n abi.encode(newBlock.mintNotes),\n abi.encode(newBlock.freezeNotes),\n abi.encode(newBlock.burnNotes)\n );\n }\n\n /// @dev send the ERC-20 tokens equivalent to the asset records being burnt. Recall that the burned record opening is contained inside the note.\n /// @param note note of type *BURN*\n function _handleWithdrawal(BurnNote memory note) internal {\n address ercTokenAddress = lookup(note.recordOpening.assetDef);\n\n // Extract recipient address\n address recipientAddress = BytesLib.toAddress(\n note.transferNote.auxInfo.extraProofBoundData,\n CAPE_BURN_MAGIC_BYTES_SIZE\n );\n SafeTransferLib.safeTransfer(\n ERC20(ercTokenAddress),\n recipientAddress,\n note.recordOpening.amount\n );\n }\n\n /// @dev Compute an upper bound on the number of records to be inserted\n function _computeNumCommitments(CapeBlock memory newBlock) internal pure returns (uint256) {\n // MintNote always has 2 commitments: mint_comm, chg_comm\n uint256 numComms = 2 * newBlock.mintNotes.length;\n for (uint256 i = 0; i < newBlock.transferNotes.length; i++) {\n numComms += newBlock.transferNotes[i].outputCommitments.length;\n }\n for (uint256 i = 0; i < newBlock.burnNotes.length; i++) {\n // Subtract one for the burn record commitment that is not inserted.\n // The function _containsBurnRecord checks that there are at least 2 output commitments.\n numComms += newBlock.burnNotes[i].transferNote.outputCommitments.length - 1;\n }\n for (uint256 i = 0; i < newBlock.freezeNotes.length; i++) {\n numComms += newBlock.freezeNotes[i].outputCommitments.length;\n }\n return numComms;\n }\n\n /// @dev Verify if a note is of type *TRANSFER*.\n /// @param note note which could be of type *TRANSFER* or *BURN*\n function _checkTransfer(TransferNote memory note) internal pure {\n require(\n !_containsBurnPrefix(note.auxInfo.extraProofBoundData),\n \"Burn prefix in transfer note\"\n );\n }\n\n /// @dev Check if a note has expired.\n /// @param note note for which we want to check its timestamp against the current block height\n function _isExpired(TransferNote memory note) internal view returns (bool) {\n return note.auxInfo.validUntil < blockHeight;\n }\n\n /// @dev Check if a burn note is well formed.\n /// @param note note of type *BURN*\n function _checkBurn(BurnNote memory note) internal view {\n bytes memory extra = note.transferNote.auxInfo.extraProofBoundData;\n require(_containsBurnPrefix(extra), \"Bad burn tag\");\n require(_containsBurnRecord(note), \"Bad record commitment\");\n }\n\n /// @dev Checks if a sequence of bytes contains hardcoded prefix.\n /// @param byteSeq sequence of bytes\n function _containsBurnPrefix(bytes memory byteSeq) internal pure returns (bool) {\n if (byteSeq.length < CAPE_BURN_MAGIC_BYTES_SIZE) {\n return false;\n }\n return\n BytesLib.equal(\n BytesLib.slice(byteSeq, 0, CAPE_BURN_MAGIC_BYTES_SIZE),\n CAPE_BURN_MAGIC_BYTES\n );\n }\n\n /// @dev Check if the burned record opening and the record commitment in position 1 are consistent.\n /// @param note note of type *BURN*\n function _containsBurnRecord(BurnNote memory note) internal view returns (bool) {\n if (note.transferNote.outputCommitments.length < 2) {\n return false;\n }\n uint256 rc = _deriveRecordCommitment(note.recordOpening);\n return rc == note.transferNote.outputCommitments[1];\n }\n\n /// @dev Compute the commitment of a record opening.\n /// @param ro record opening\n function _deriveRecordCommitment(RecordOpening memory ro) internal view returns (uint256 rc) {\n require(ro.assetDef.policy.revealMap < 2**12, \"Reveal map exceeds 12 bits\");\n\n // No overflow check, only 12 bits in reveal map\n uint256 revealMapAndFreezeFlag = 2 *\n ro.assetDef.policy.revealMap +\n (ro.freezeFlag ? 1 : 0);\n\n // blind in front of rest -> 13 elements, pad to 15 (5 x 3)\n uint256[15] memory inputs = [\n ro.blind,\n ro.amount,\n ro.assetDef.code,\n ro.userAddr.x,\n ro.userAddr.y,\n ro.assetDef.policy.auditorPk.x,\n ro.assetDef.policy.auditorPk.y,\n ro.assetDef.policy.credPk.x,\n ro.assetDef.policy.credPk.y,\n ro.assetDef.policy.freezerPk.x,\n ro.assetDef.policy.freezerPk.y,\n revealMapAndFreezeFlag,\n ro.assetDef.policy.revealThreshold,\n 0,\n 0\n ];\n\n return RescueLib.commit(inputs);\n }\n\n /// @dev An overloaded function (one for each note type) to prepare all inputs necessary for batch verification of the plonk proof.\n /// @param note note of type *TRANSFER*\n function _prepareForProofVerification(TransferNote memory note)\n internal\n view\n returns (\n IPlonkVerifier.VerifyingKey memory vk,\n uint256[] memory publicInput,\n IPlonkVerifier.PlonkProof memory proof,\n bytes memory transcriptInitMsg\n )\n {\n // load the correct (hardcoded) vk\n // slither-disable-next-line calls-loop\n vk = VerifyingKeys.getVkById(\n VerifyingKeys.getEncodedId(\n uint8(NoteType.TRANSFER),\n uint8(note.inputNullifiers.length),\n uint8(note.outputCommitments.length),\n uint8(_recordsMerkleTree.getHeight())\n )\n );\n // prepare public inputs\n // 4: root, native_asset_code, valid_until, fee\n // 2: audit_memo.ephemeral_key (x and y)\n publicInput = new uint256[](\n 4 +\n note.inputNullifiers.length +\n note.outputCommitments.length +\n 2 +\n note.auditMemo.data.length\n );\n publicInput[0] = note.auxInfo.merkleRoot;\n publicInput[1] = CAP_NATIVE_ASSET_CODE;\n publicInput[2] = note.auxInfo.validUntil;\n publicInput[3] = note.auxInfo.fee;\n {\n uint256 idx = 4;\n for (uint256 i = 0; i < note.inputNullifiers.length; i++) {\n publicInput[idx + i] = note.inputNullifiers[i];\n }\n idx += note.inputNullifiers.length;\n\n for (uint256 i = 0; i < note.outputCommitments.length; i++) {\n publicInput[idx + i] = note.outputCommitments[i];\n }\n idx += note.outputCommitments.length;\n\n publicInput[idx] = note.auditMemo.ephemeralKey.x;\n publicInput[idx + 1] = note.auditMemo.ephemeralKey.y;\n idx += 2;\n\n for (uint256 i = 0; i < note.auditMemo.data.length; i++) {\n publicInput[idx + i] = note.auditMemo.data[i];\n }\n }\n\n // extract out proof\n proof = note.proof;\n\n // prepare transcript init messages\n transcriptInitMsg = abi.encodePacked(\n EdOnBN254.serialize(note.auxInfo.txnMemoVerKey),\n note.auxInfo.extraProofBoundData\n );\n }\n\n /// @dev An overloaded function (one for each note type) to prepare all inputs necessary for batch verification of the plonk proof.\n /// @param note note of type *BURN*\n function _prepareForProofVerification(BurnNote memory note)\n internal\n view\n returns (\n IPlonkVerifier.VerifyingKey memory,\n uint256[] memory,\n IPlonkVerifier.PlonkProof memory,\n bytes memory\n )\n {\n return _prepareForProofVerification(note.transferNote);\n }\n\n /// @dev An overloaded function (one for each note type) to prepare all inputs necessary for batch verification of the plonk proof.\n /// @param note note of type *MINT*\n function _prepareForProofVerification(MintNote memory note)\n internal\n view\n returns (\n IPlonkVerifier.VerifyingKey memory vk,\n uint256[] memory publicInput,\n IPlonkVerifier.PlonkProof memory proof,\n bytes memory transcriptInitMsg\n )\n {\n // load the correct (hardcoded) vk\n // slither-disable-next-line calls-loop\n vk = VerifyingKeys.getVkById(\n VerifyingKeys.getEncodedId(\n uint8(NoteType.MINT),\n 1, // num of input\n 2, // num of output\n uint8(_recordsMerkleTree.getHeight())\n )\n );\n\n // prepare public inputs\n // 9: see below; 8: asset policy; rest: audit memo\n publicInput = new uint256[](9 + 8 + 2 + note.auditMemo.data.length);\n publicInput[0] = note.auxInfo.merkleRoot;\n publicInput[1] = CAP_NATIVE_ASSET_CODE;\n publicInput[2] = note.inputNullifier;\n publicInput[3] = note.auxInfo.fee;\n publicInput[4] = note.mintComm;\n publicInput[5] = note.chgComm;\n publicInput[6] = note.mintAmount;\n publicInput[7] = note.mintAssetDef.code;\n publicInput[8] = note.mintInternalAssetCode;\n\n publicInput[9] = note.mintAssetDef.policy.revealMap;\n publicInput[10] = note.mintAssetDef.policy.auditorPk.x;\n publicInput[11] = note.mintAssetDef.policy.auditorPk.y;\n publicInput[12] = note.mintAssetDef.policy.credPk.x;\n publicInput[13] = note.mintAssetDef.policy.credPk.y;\n publicInput[14] = note.mintAssetDef.policy.freezerPk.x;\n publicInput[15] = note.mintAssetDef.policy.freezerPk.y;\n publicInput[16] = note.mintAssetDef.policy.revealThreshold;\n\n {\n publicInput[17] = note.auditMemo.ephemeralKey.x;\n publicInput[18] = note.auditMemo.ephemeralKey.y;\n\n uint256 idx = 19;\n for (uint256 i = 0; i < note.auditMemo.data.length; i++) {\n publicInput[idx + i] = note.auditMemo.data[i];\n }\n }\n\n // extract out proof\n proof = note.proof;\n\n // prepare transcript init messages\n transcriptInitMsg = EdOnBN254.serialize(note.auxInfo.txnMemoVerKey);\n }\n\n /// @dev An overloaded function (one for each note type) to prepare all inputs necessary for batch verification of the plonk proof.\n /// @param note note of type *FREEZE*\n function _prepareForProofVerification(FreezeNote memory note)\n internal\n view\n returns (\n IPlonkVerifier.VerifyingKey memory vk,\n uint256[] memory publicInput,\n IPlonkVerifier.PlonkProof memory proof,\n bytes memory transcriptInitMsg\n )\n {\n // load the correct (hardcoded) vk\n // slither-disable-next-line calls-loop\n vk = VerifyingKeys.getVkById(\n VerifyingKeys.getEncodedId(\n uint8(NoteType.FREEZE),\n uint8(note.inputNullifiers.length),\n uint8(note.outputCommitments.length),\n uint8(_recordsMerkleTree.getHeight())\n )\n );\n\n // prepare public inputs\n publicInput = new uint256[](\n 3 + note.inputNullifiers.length + note.outputCommitments.length\n );\n publicInput[0] = note.auxInfo.merkleRoot;\n publicInput[1] = CAP_NATIVE_ASSET_CODE;\n publicInput[2] = note.auxInfo.fee;\n {\n uint256 idx = 3;\n for (uint256 i = 0; i < note.inputNullifiers.length; i++) {\n publicInput[idx + i] = note.inputNullifiers[i];\n }\n idx += note.inputNullifiers.length;\n\n for (uint256 i = 0; i < note.outputCommitments.length; i++) {\n publicInput[idx + i] = note.outputCommitments[i];\n }\n }\n\n // extract out proof\n proof = note.proof;\n\n // prepare transcript init messages\n transcriptInitMsg = EdOnBN254.serialize(note.auxInfo.txnMemoVerKey);\n }\n\n function getRootValue() external view returns (uint256) {\n return _recordsMerkleTree.getRootValue();\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@rari-capital/solmate/src/utils/SafeTransferLib.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\nlibrary SafeTransferLib {\n /*///////////////////////////////////////////////////////////////\n ETH OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferETH(address to, uint256 amount) internal {\n bool callStatus;\n\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n callStatus := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n require(callStatus, \"ETH_TRANSFER_FAILED\");\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC20 OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferFrom(\n ERC20 token,\n address from,\n address to,\n uint256 amount\n ) internal {\n bool callStatus;\n\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata to memory piece by piece:\n mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.\n mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the \"from\" argument.\n mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the \"to\" argument.\n mstore(add(freeMemoryPointer, 68), amount) // Finally append the \"amount\" argument. No mask as it's a full 32 byte value.\n\n // Call the token and store if it succeeded or not.\n // We use 100 because the calldata length is 4 + 32 * 3.\n callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)\n }\n\n require(didLastOptionalReturnCallSucceed(callStatus), \"TRANSFER_FROM_FAILED\");\n }\n\n function safeTransfer(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool callStatus;\n\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata to memory piece by piece:\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Finally append the \"amount\" argument. No mask as it's a full 32 byte value.\n\n // Call the token and store if it succeeded or not.\n // We use 68 because the calldata length is 4 + 32 * 2.\n callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)\n }\n\n require(didLastOptionalReturnCallSucceed(callStatus), \"TRANSFER_FAILED\");\n }\n\n function safeApprove(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool callStatus;\n\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata to memory piece by piece:\n mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Finally append the \"amount\" argument. No mask as it's a full 32 byte value.\n\n // Call the token and store if it succeeded or not.\n // We use 68 because the calldata length is 4 + 32 * 2.\n callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)\n }\n\n require(didLastOptionalReturnCallSucceed(callStatus), \"APPROVE_FAILED\");\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL HELPER LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {\n assembly {\n // Get how many bytes the call returned.\n let returnDataSize := returndatasize()\n\n // If the call reverted:\n if iszero(callStatus) {\n // Copy the revert message into memory.\n returndatacopy(0, 0, returnDataSize)\n\n // Revert with the same message.\n revert(0, returnDataSize)\n }\n\n switch returnDataSize\n case 32 {\n // Copy the return data into memory.\n returndatacopy(0, 0, returnDataSize)\n\n // Set success to whether it returned true.\n success := iszero(iszero(mload(0)))\n }\n case 0 {\n // There was no return data.\n success := 1\n }\n default {\n // It returned some malformed input.\n success := 0\n }\n }\n }\n}\n" + }, + "solidity-bytes-utils/contracts/BytesLib.sol": { + "content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá \n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\n\nlibrary BytesLib {\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n )\n internal\n pure\n returns (bytes memory)\n {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(0x40, and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n ))\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(\n sc,\n add(\n and(\n fslot,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n ),\n and(mload(mc), mask)\n )\n )\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n )\n internal\n pure\n returns (bytes memory)\n {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1 , \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint256 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(\n bytes storage _preBytes,\n bytes memory _postBytes\n )\n internal\n view\n returns (bool)\n {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {} eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n" + }, + "contracts/libraries/AccumulatingArray.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\n/// @title AccumulatingArray library\n/// @dev This library simplifies inserting elements into an array by keeping track\n/// of the insertion index.\n\nlibrary AccumulatingArray {\n struct Data {\n uint256[] items;\n uint256 index;\n }\n\n /// @dev Create a new AccumulatingArray\n /// @param length the number of items that will be inserted\n function create(uint256 length) internal pure returns (Data memory) {\n return Data(new uint256[](length), 0);\n }\n\n /// @param items the items to accumulate\n /// @dev Will revert if items past length are added.\n function add(Data memory self, uint256[] memory items) internal pure {\n for (uint256 i = 0; i < items.length; i++) {\n self.items[i + self.index] = items[i];\n }\n self.index += items.length;\n }\n\n /// @param item the item to accumulate.\n /// @dev Will revert if items past length are added.\n function add(Data memory self, uint256 item) internal pure {\n self.items[self.index] = item;\n self.index += 1;\n }\n\n function isEmpty(Data memory self) internal pure returns (bool) {\n return (self.index == 0);\n }\n}\n" + }, + "contracts/libraries/RescueLib.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nlibrary RescueLib {\n /// The constants are obtained from the Sage script\n /// https://github.com/EspressoSystems/Marvellous/blob/fcd4c41672f485ac2f62526bc87a16789d4d0459/rescue254.sage\n\n // These constants are no longer used, left here for readability.\n // uint256 private constant _N_ROUNDS = 12;\n // uint256 private constant _STATE_SIZE = 4;\n // uint256 private constant _SCHEDULED_KEY_SIZE = (2 * _N_ROUNDS + 1) * _STATE_SIZE;\n // uint256 private constant _ALPHA = 5;\n\n // Obtained by running KeyScheduling([0,0,0,0]). See Algorithm 2 of AT specification document.\n\n uint256 private constant _PRIME =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n uint256 private constant _ALPHA_INV =\n 17510594297471420177797124596205820070838691520332827474958563349260646796493;\n\n // MDS is hardcoded\n function _linearOp(\n uint256 s0,\n uint256 s1,\n uint256 s2,\n uint256 s3\n )\n private\n pure\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n // Matrix multiplication\n unchecked {\n return (\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575808479992,\n s0,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575806058117,\n s1,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575491214367,\n s2,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186535831058117,\n s3,\n _PRIME\n ),\n mulmod(19500, s0, _PRIME) +\n mulmod(3026375, s1, _PRIME) +\n mulmod(393529500, s2, _PRIME) +\n mulmod(49574560750, s3, _PRIME),\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575808491587,\n s0,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575807886437,\n s1,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186575729688812,\n s2,\n _PRIME\n ) +\n mulmod(\n 21888242871839275222246405745257275088548364400416034343698204186565891044437,\n s3,\n _PRIME\n ),\n mulmod(156, s0, _PRIME) +\n mulmod(20306, s1, _PRIME) +\n mulmod(2558556, s2, _PRIME) +\n mulmod(320327931, s3, _PRIME)\n );\n }\n }\n\n function _expAlphaInv4Setup(uint256[6] memory scratch) private pure {\n assembly {\n let p := scratch\n mstore(p, 0x20) // Length of Base\n mstore(add(p, 0x20), 0x20) // Length of Exponent\n mstore(add(p, 0x40), 0x20) // Length of Modulus\n mstore(add(p, 0x80), _ALPHA_INV) // Exponent\n mstore(add(p, 0xa0), _PRIME) // Modulus\n }\n }\n\n function _expAlphaInv4(\n uint256[6] memory scratch,\n uint256 s0,\n uint256 s1,\n uint256 s2,\n uint256 s3\n )\n private\n view\n returns (\n uint256 o0,\n uint256 o1,\n uint256 o2,\n uint256 o3\n )\n {\n assembly {\n // define pointer\n let p := scratch\n let basep := add(p, 0x60)\n mstore(basep, s0) // Base\n // store data assembly-favouring ways\n pop(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, basep, 0x20))\n // data\n o0 := mload(basep)\n mstore(basep, s1) // Base\n pop(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, basep, 0x20))\n // data\n o1 := mload(basep)\n mstore(basep, s2) // Base\n pop(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, basep, 0x20))\n // data\n o2 := mload(basep)\n mstore(basep, s3) // Base\n pop(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, basep, 0x20))\n // data\n o3 := mload(basep)\n }\n }\n\n // Computes the Rescue permutation on some input\n // Recall that the scheduled key is precomputed in our case\n // @param input input for the permutation\n // @return permutation output\n function perm(\n // slither-disable-next-line write-after-write\n uint256 s0,\n // slither-disable-next-line write-after-write\n uint256 s1,\n // slither-disable-next-line write-after-write\n uint256 s2,\n // slither-disable-next-line write-after-write\n uint256 s3\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n // slither-disable-next-line uninitialized-local\n uint256[6] memory alphaInvScratch;\n\n _expAlphaInv4Setup(alphaInvScratch);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 14613516837064033601098425266946467918409544647446217386229959902054563533267,\n s1 + 376600575581954944138907282479272751264978206975465380433764825531344567663,\n s2 + 7549886658634274343394883631367643327196152481472281919735617268044202589860,\n s3 + 3682071510138521345600424597536598375718773365536872232193107639375194756918\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 18657517374128716281071590782771170166993445602755371021955596036781411817786;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 7833794394096838639430144230563403530989402760602204539559270044687522640191;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 21303828694647266539931030987057572024333442749881970102454081226349775826204;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 10601447988834057856019990466870413629636256450824419416829818546423193802418;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 3394657260998945409283098835682964352503279447198495330506177586645995289229,\n s1 + 18437084083724939316390841967750487133622937044030373241106776324730657101302,\n s2 + 9281739916935170266925270432337475828741505406943764438550188362765269530037,\n s3 + 7363758719535652813463843693256839865026387361836644774317493432208443086206\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 307094088106440279963968943984309088038734274328527845883669678290790702381;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 20802277384865839022876847241719852837518994021170013346790603773477912819001;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 19754579269464973651593381036132218829220609572271224048608091445854164824042;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 3618840933841571232310395486452077846249117988789467996234635426899783130819;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 2604166168648013711791424714498680546427073388134923208733633668316805639713,\n s1 + 21355705619901626246699129842094174300693414345856149669339147704587730744579,\n s2 + 492957643799044929042114590851019953669919577182050726596188173945730031352,\n s3 + 8495959434717951575638107349559891417392372124707619959558593515759091841138\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 15608173629791582453867933160400609222904457931922627396107815347244961625587;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 16346164988481725869223011419855264063160651334419415042919928342589111681923;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 21085652277104054699752179865196164165969290053517659864117475352262716334100;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 20640310021063232205677193759981403045043444605175178332133134865746039279935;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 6015589261538006311719125697023069952804098656652050863009463360598997670240,\n s1 + 12498423882721726012743791752811798719201859023192663855805526312393108407357,\n s2 + 10785527781711732350693172404486938622378708235957779975342240483505724965040,\n s3 + 5563181134859229953817163002660048854420912281911747312557025480927280392569\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 4585980485870975597083581718044393941512074846925247225127276913719050121968;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 8135760428078872176830812746579993820254685977237403304445687861806698035222;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 4525715538433244696411192727226186804883202134636681498489663161593606654720;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 2537497100749435007113677475828631400227339157221711397900070636998427379023;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 6957758175844522415482704083077249782181516476067074624906502033584870962925,\n s1 + 17134288156316028142861248367413235848595762718317063354217292516610545487813,\n s2 + 20912428573104312239411321877435657586184425249645076131891636094671938892815,\n s3 + 16000236205755938926858829908701623009580043315308207671921283074116709575629\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 10226182617544046880850643054874064693998595520540061157646952229134207239372;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 18584346134948015676264599354709457865255277240606855245909703396343731224626;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 9263628039314899758000383385773954136696958567872461042004915206775147151562;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 21095966719856094705113273596585696209808876361583941931684481364905087347856;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 2671157351815122058649197205531097090514563992249109660044882868649840700911,\n s1 + 19371695134219415702961622134896564229962454573253508904477489696588594622079,\n s2 + 5458968308231210904289987830881528056037123818964633914555287871152343390175,\n s3 + 7336332584551233792026746889434554547883125466404119632794862500961953384162\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 10351436748086126474964482623536554036637945319698748519226181145454116702488;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 10588209357420186457766745724579739104572139534486480334142455690083813419064;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 14330277147584936710957102218096795520430543834717433464500965846826655802131;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 20752197679372238381408962682213349118865256502118746003818603260257076802028;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 19390446529582160674621825412345750405397926216690583196542690617266028463414,\n s1 + 4169994013656329171830126793466321040216273832271989491631696813297571003664,\n s2 + 3014817248268674641565961681956715664833306954478820029563459099892548946802,\n s3 + 14285412497877984113655094566695921704826935980354186365694472961163628072901\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 16224484149774307577146165975762490690838415946665379067259822320752729067513;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 5404416528124718330316441408560295270695591369912905197499507811036327404407;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 20127204244332635127213425090893250761286848618448128307344971109698523903374;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 14939477686176063572999014162186372798386193194442661892600584389296609365740;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 183740587182448242823071506013879595265109215202349952517434740768878294134,\n s1 + 15366166801397358994305040367078329374182896694582870542425225835844885654667,\n s2 + 10066796014802701613007252979619633540090232697942390802486559078446300507813,\n s3 + 4824035239925904398047276123907644574421550988870123756876333092498925242854\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 5526416022516734657935645023952329824887761902324086126076396040056459740202;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 18157816292703983306114736850721419851645159304249709756659476015594698876611;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 767446206481623130855439732549764381286210118638028499466788453347759203223;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 16303412231051555792435190427637047658258796056382698277687500021321460387129;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 15475465085113677237835653765189267963435264152924949727326000496982746660612,\n s1 + 14574823710073720047190393602502575509282844662732045439760066078137662816054,\n s2 + 13746490178929963947720756220409862158443939172096620003896874772477437733602,\n s3 + 13804898145881881347835367366352189037341704254740510664318597456840481739975\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 3523599105403569319090449327691358425990456728660349400211678603795116364226;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 8632053982708637954870974502506145434219829622278773822242070316888003350278;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 20293222318844554840191640739970825558851264905959070636369796127300969629060;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 7583204376683983181255811699503668584283525661852773339144064901897953897564;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 7562572155566079175343789986900217168516831778275127159068657756836798778249,\n s1 + 12689811910161401007144285031988539999455902164332232460061366402869461973371,\n s2 + 21878400680687418538050108788381481970431106443696421074205107984690362920637,\n s3 + 3428721187625124675258692786364137915132424621324969246210899039774126165479\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 2552744099402346352193097862110515290335034445517764751557635302899937367219;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 13706727374402840004346872704605212996406886221231239230397976011930486183550;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 19786308443934570499119114884492461847023732197118902978413499381102456961966;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 11767081169862697956461405434786280425108140215784390008330611807075539962898;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 1273319740931699377003430019539548781935202579355152343831464213279794249000,\n s1 + 20225620070386241931202098463018472034137960205721651875253423327929063224115,\n s2 + 13107884970924459680133954992354588464904218518440707039430314610799573960437,\n s3 + 10574066469653966216567896842413898230152427846140046825523989742590727910280\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 21386271527766270535632132320974945129946865648321206442664310421414128279311;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 15743262855527118149527268525857865250723531109306484598629175225221686341453;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 16251140915157602891864152518526119259367827194524273940185283798897653655734;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 5420158299017134702074915284768041702367316125403978919545323705661634647751;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n (s0, s1, s2, s3) = _expAlphaInv4(\n alphaInvScratch,\n s0 + 14555572526833606349832007897859411042036463045080050783981107823326880950231,\n s1 + 15234942318869557310939446038663331226792664588406507247341043508129993934298,\n s2 + 19560004467494472556570844694553210033340577742756929194362924850760034377042,\n s3 + 21851693551359717578445799046408060941161959589978077352548456186528047792150\n );\n }\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n uint256 tmp = s0 +\n 19076469206110044175016166349949136119962165667268661130584159239385341119621;\n s0 = mulmod(tmp, tmp, _PRIME);\n s0 = mulmod(s0, s0, _PRIME);\n s0 = mulmod(s0, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s1 +\n 19132104531774396501521959463346904008488403861940301898725725957519076019017;\n s1 = mulmod(tmp, tmp, _PRIME);\n s1 = mulmod(s1, s1, _PRIME);\n s1 = mulmod(s1, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s2 +\n 6606159937109409334959297158878571243749055026127553188405933692223704734040;\n s2 = mulmod(tmp, tmp, _PRIME);\n s2 = mulmod(s2, s2, _PRIME);\n s2 = mulmod(s2, tmp, _PRIME);\n }\n unchecked {\n uint256 tmp = s3 +\n 13442678592538344046772867528443594004918096722084104155946229264098946917042;\n s3 = mulmod(tmp, tmp, _PRIME);\n s3 = mulmod(s3, s3, _PRIME);\n s3 = mulmod(s3, tmp, _PRIME);\n }\n\n (s0, s1, s2, s3) = _linearOp(s0, s1, s2, s3);\n\n unchecked {\n return (\n s0 + 11975757366382164299373991853632416786161357061467425182041988114491638264212,\n s1 + 10571372363668414752587603575617060708758897046929321941050113299303675014148,\n s2 + 5405426474713644587066466463343175633538103521677501186003868914920014287031,\n s3 + 18665277628144856329335676361545218245401014824195451740181902217370165017984\n );\n }\n }\n\n // Computes the hash of three field elements and returns a single element\n // In our case the rate is 3 and the capacity is 1\n // This hash function the one used in the Records Merkle tree.\n // @param a first element\n // @param b second element\n // @param c third element\n // @return the first element of the Rescue state\n function hash(\n uint256 a,\n uint256 b,\n uint256 c\n ) public view returns (uint256 o) {\n (o, a, b, c) = perm(a % _PRIME, b % _PRIME, c % _PRIME, 0);\n o %= _PRIME;\n }\n\n function checkBounded(uint256[15] memory inputs) internal pure {\n for (uint256 i = 0; i < inputs.length; ++i) {\n require(inputs[i] < _PRIME, \"inputs must be below _PRIME\");\n }\n }\n\n // This function is external to ensure that the solidity compiler generates\n // a separate library contract. This is required to reduce the size of the\n // CAPE contract.\n function commit(uint256[15] memory inputs) external view returns (uint256) {\n checkBounded(inputs);\n\n uint256 a;\n uint256 b;\n uint256 c;\n uint256 d;\n\n for (uint256 i = 0; i < 5; i++) {\n unchecked {\n (a, b, c, d) = perm(\n (a + inputs[3 * i + 0]) % _PRIME,\n (b + inputs[3 * i + 1]) % _PRIME,\n (c + inputs[3 * i + 2]) % _PRIME,\n d\n );\n\n (a, b, c, d) = (a % _PRIME, b % _PRIME, c % _PRIME, d % _PRIME);\n }\n }\n\n return a;\n }\n}\n" + }, + "contracts/libraries/VerifyingKeys.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./Transfer1In2Out24DepthVk.sol\";\nimport \"./Transfer2In2Out24DepthVk.sol\";\nimport \"./Transfer2In3Out24DepthVk.sol\";\nimport \"./Transfer3In3Out24DepthVk.sol\";\nimport \"./Mint1In2Out24DepthVk.sol\";\nimport \"./Freeze2In2Out24DepthVk.sol\";\nimport \"./Freeze3In3Out24DepthVk.sol\";\n\nlibrary VerifyingKeys {\n function getVkById(uint256 encodedId)\n external\n pure\n returns (IPlonkVerifier.VerifyingKey memory)\n {\n if (encodedId == getEncodedId(0, 1, 2, 24)) {\n // transfer/burn-1-input-2-output-24-depth\n return Transfer1In2Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(0, 2, 2, 24)) {\n // transfer/burn-2-input-2-output-24-depth\n return Transfer2In2Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(0, 2, 3, 24)) {\n // transfer/burn-2-input-3-output-24-depth\n return Transfer2In3Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(0, 3, 3, 24)) {\n // transfer/burn-3-input-3-output-24-depth\n return Transfer3In3Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(1, 1, 2, 24)) {\n // mint-1-input-2-output-24-depth\n return Mint1In2Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(2, 2, 2, 24)) {\n // freeze-2-input-2-output-24-depth\n return Freeze2In2Out24DepthVk.getVk();\n } else if (encodedId == getEncodedId(2, 3, 3, 24)) {\n // freeze-3-input-3-output-24-depth\n return Freeze3In3Out24DepthVk.getVk();\n } else {\n revert(\"Unknown vk ID\");\n }\n }\n\n // returns (noteType, numInput, numOutput, treeDepth) as a 4*8 = 32 byte = uint256\n // as the encoded ID.\n function getEncodedId(\n uint8 noteType,\n uint8 numInput,\n uint8 numOutput,\n uint8 treeDepth\n ) public pure returns (uint256 encodedId) {\n assembly {\n encodedId := add(\n shl(24, noteType),\n add(shl(16, numInput), add(shl(8, numOutput), treeDepth))\n )\n }\n }\n}\n" + }, + "contracts/interfaces/IPlonkVerifier.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../libraries/BN254.sol\";\n\ninterface IPlonkVerifier {\n // Flatten out TurboPlonk proof\n struct PlonkProof {\n // the first 5 are 4 inputs and 1 output wire poly commmitments\n // i.e., batch_proof.wires_poly_comms_vec.iter()\n // wire0 is 32 bytes which is a pointer to BN254.G1Point\n BN254.G1Point wire0; // 0x00\n BN254.G1Point wire1; // 0x20\n BN254.G1Point wire2; // 0x40\n BN254.G1Point wire3; // 0x60\n BN254.G1Point wire4; // 0x80\n // the next one is the product permutation poly commitment\n // i.e., batch_proof.prod_perm_poly_comms_vec.iter()\n BN254.G1Point prodPerm; // 0xA0\n // the next 5 are split quotient poly commmitments\n // i.e., batch_proof.split_quot_poly_comms\n BN254.G1Point split0; // 0xC0\n BN254.G1Point split1; // 0xE0\n BN254.G1Point split2; // 0x100\n BN254.G1Point split3; // 0x120\n BN254.G1Point split4; // 0x140\n // witness poly com for aggregated opening at `zeta`\n // i.e., batch_proof.opening_proof\n BN254.G1Point zeta; // 0x160\n // witness poly com for shifted opening at `zeta * \\omega`\n // i.e., batch_proof.shifted_opening_proof\n BN254.G1Point zetaOmega; // 0x180\n // wire poly eval at `zeta`\n uint256 wireEval0; // 0x1A0\n uint256 wireEval1; // 0x1C0\n uint256 wireEval2; // 0x1E0\n uint256 wireEval3; // 0x200\n uint256 wireEval4; // 0x220\n // extended permutation (sigma) poly eval at `zeta`\n // last (sigmaEval4) is saved by Maller Optimization\n uint256 sigmaEval0; // 0x240\n uint256 sigmaEval1; // 0x260\n uint256 sigmaEval2; // 0x280\n uint256 sigmaEval3; // 0x2A0\n // product permutation poly eval at `zeta * \\omega`\n uint256 prodPermZetaOmegaEval; // 0x2C0\n }\n\n // The verifying key for Plonk proofs.\n struct VerifyingKey {\n uint256 domainSize; // 0x00\n uint256 numInputs; // 0x20\n // commitment to extended perm (sigma) poly\n BN254.G1Point sigma0; // 0x40\n BN254.G1Point sigma1; // 0x60\n BN254.G1Point sigma2; // 0x80\n BN254.G1Point sigma3; // 0xA0\n BN254.G1Point sigma4; // 0xC0\n // commitment to selector poly\n // first 4 are linear combination selector\n BN254.G1Point q1; // 0xE0\n BN254.G1Point q2; // 0x100\n BN254.G1Point q3; // 0x120\n BN254.G1Point q4; // 0x140\n // multiplication selector for 1st, 2nd wire\n BN254.G1Point qM12; // 0x160\n // multiplication selector for 3rd, 4th wire\n BN254.G1Point qM34; // 0x180\n // output selector\n BN254.G1Point qO; // 0x1A0\n // constant term selector\n BN254.G1Point qC; // 0x1C0\n // rescue selector qH1 * w_ai^5\n BN254.G1Point qH1; // 0x1E0\n // rescue selector qH2 * w_bi^5\n BN254.G1Point qH2; // 0x200\n // rescue selector qH3 * w_ci^5\n BN254.G1Point qH3; // 0x220\n // rescue selector qH4 * w_di^5\n BN254.G1Point qH4; // 0x240\n // elliptic curve selector\n BN254.G1Point qEcc; // 0x260\n }\n\n /// @dev Batch verify multiple TurboPlonk proofs.\n /// @param verifyingKeys An array of verifying keys\n /// @param publicInputs A two-dimensional array of public inputs.\n /// @param proofs An array of Plonk proofs\n /// @param extraTranscriptInitMsgs An array of bytes from\n /// transcript initialization messages\n /// @return _ A boolean that is true for successful verification, false otherwise\n function batchVerify(\n VerifyingKey[] memory verifyingKeys,\n uint256[][] memory publicInputs,\n PlonkProof[] memory proofs,\n bytes[] memory extraTranscriptInitMsgs\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IRecordsMerkleTree.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\ninterface IRecordsMerkleTree {\n /// @param elements The list of elements to be appended to the current merkle tree described by the frontier.\n function updateRecordsMerkleTree(uint256[] memory elements) external;\n\n /// @notice Returns the root value of the Merkle tree.\n function getRootValue() external view returns (uint256);\n\n /// @notice Returns the height of the Merkle tree.\n function getHeight() external view returns (uint8);\n\n /// @notice Returns the number of leaves of the Merkle tree.\n function getNumLeaves() external view returns (uint64);\n}\n" + }, + "contracts/RootStore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\ncontract RootStore {\n uint256[] internal _roots;\n mapping(uint256 => bool) internal _rootsMap;\n uint64 internal _writeHead;\n\n /// @dev Create a root store.\n /// @param nRoots The maximum number of roots to store\n constructor(uint64 nRoots) {\n // Set up the circular buffer for handling the last N roots\n require(nRoots > 1, \"A least 2 roots required\");\n\n _roots = new uint256[](nRoots);\n\n // Initially all roots are set to zero.\n // This value is such that no adversary can extend a branch from this root node.\n // See proposition 2, page 48 of the AT-Spec document EspressoSystems/AT-spec@01f71ce\n }\n\n /// @dev Add a root value. Only keep the latest nRoots ones.\n /// @param newRoot The value of the new root\n function _addRoot(uint256 newRoot) internal {\n require(!_rootsMap[newRoot], \"Root already exists\");\n\n // Ensure the root we will \"overwrite\" is removed.\n _rootsMap[_roots[_writeHead]] = false;\n\n _roots[_writeHead] = newRoot;\n _rootsMap[newRoot] = true;\n\n _writeHead = (_writeHead + 1) % uint64(_roots.length);\n }\n\n /// @dev Is the root value contained in the store?\n /// @param root The root value to find\n /// @return _ True if the root value is in the store, false otherwise\n function _containsRoot(uint256 root) internal view returns (bool) {\n return _rootsMap[root];\n }\n\n /// @dev Raise an exception if the root is not present in the store.\n /// @param root The required root value\n function _checkContainsRoot(uint256 root) internal view {\n require(_containsRoot(root), \"Root not found\");\n }\n}\n" + }, + "@rari-capital/solmate/src/tokens/ERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*///////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*///////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*///////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*///////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n bytes32 public constant PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*///////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*///////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n )\n );\n\n address recoveredAddress = ecrecover(digest, v, r, s);\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n" + }, + "contracts/libraries/Transfer1In2Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Transfer1In2Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 32768)\n // num of public inputs\n mstore(add(vk, 0x20), 14)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 6451930258054036397165544866644311272180786776693649154889113517935138989324\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 15824498031290932840309269587075035510403426361110328301862825820425402064333\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 16567945706248183214406921539823721483157024902030706018155219832331943151521\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 14506648136467119081958160505454685757895812203258866143116417397069305366174\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 16908805137848644970538829805684573945187052776129406508429516788865993229946\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 13370902069114408370627021011309095482019563080650295231694581484651030202227\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 11385428061273012554614867838291301202096376350855764984558871671579621291507\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 18938480909096008246537758317235530495583632544865390355616243879170108311037\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 7250836052061444170671162428779548720754588271620290284029438087321333136859\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 9774478170511284714380468511107372909275276960243638784016266344709965751507\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 2164661706057106993702119971892524764909406587180616475316536801798272746351\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 7993083931046493938644389635874939373576598203553188654440768055247347522377\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 17875027092910639802264620931724329796279457509298747494670931666396434012177\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 12276180841132702377773827582398158204508221552359644390751974783173207949116\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 6923045257159434019788850173231395134054684072354814328515094196682490129996\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 10297389981574891432841377306749459633586002482842974197875786670892058142179\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 13566140293342467207563198706820126266175769850278450464476746689910443370750\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 4337013617009771491102950113766314929630396941539697665107262932887431611820\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 19545356440018631139549838928930231615194677294299230322568967706100221743452\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 3905268653568739552774781017975590296651581349403516285498718251384231803637\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 3633513776458243190609011598510312470369153119749343878250857605063953894824\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 10348854780537633653024803962077925757963724802390956695225993897601858375068\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 10515123958235902109894586452633863486298290064878690665500349352367945576213\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 20835963785046732330293306231553834880816750576829504030205004088050809531737\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 10349250837084111252673833558497412287345352572732754388450385078539897036072\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 1295954576893766564415821998145161393110346678014886452040838119568563355556\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 18595738613642013642528283665640490180800278502934355301953048187579782737773\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 5708601727819525671780050950771464619626673626810479676243974296923430650735\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 8105844768413379370590866345497514518639783589779028631263566798017351944465\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 13767799708582015119198203890136804463714948257729839866946279972890684141171\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 13976995316216184532948677497270469464100744949177652840098916826286666391978\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 8782060747227562892357029272916715317651514559557103332761644499318601665300\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 10423258206189675762927713311069351374538317153673220039972782365668263479097\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 12712089727236847935392559371166622501626155101609755726562266635070650647609\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 3447947975392962233948092031223758925923495365282112464857270024948603045088\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 4655198050073279486560411245172865913095816956325221266986314415391129730949\n )\n }\n }\n}\n" + }, + "contracts/libraries/Transfer2In2Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Transfer2In2Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 32768)\n // num of public inputs\n mstore(add(vk, 0x20), 27)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 2353344940323935826134936223947938042521909475033774928828281661731550798722\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 9746655158250922067275109215926891774244956160343543537816404835253168644024\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 15455409296542685326830249024223724266624290984578410657713086954481835262616\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 18311379816054123251097409624258299432408683566103718315014121691958807960547\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 3595102568308999621710931895728700858137670894580826466196432246884451756647\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 5971868016111020985417776938700261612639243638290968867440360355753182506016\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 12443289603239702012200478229424802817855243081906319312702825218898138895946\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 14108881420049829870828878537593066975275378607590487898362908473190089969939\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 19679657199741651524390089978450662678686454680964744364368691879627016432652\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 17114067594856558864780849616452660298251042000563020846487894545389438664806\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 4521205613646422234630873762189179209607994647697100090154823061235920789353\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 16106449496625400183304424755719536524421029289605758534728292280016648447637\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 15558337488326969806891656016031810341177100586194811207644366322955582958290\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 154404024660163916069895563430486111291743096749375581648108814279740019496\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 10968315091130697826739702003431871061194509005508422925553623050382577326217\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 15427520064071248215056685014173235486104450904391795026852773491856938894709\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 18552120566932429867086353275996329695634259700395564758868503989836119743976\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 3758067104786429430903075307629079520236919298153864746942709833835554967358\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 15572105585408879365916525794377657194208962207139936775774251314043834098564\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 6020958592977720912767721649577520866900127639444801108025166566775601659967\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 7222736374399006211510699304087942059126683193629769887877014686905908945806\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 3206829195840321731462512861208486643839466222481973961857037286401683735687\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 3354591448826521438380040598853232839565248677422944332090180952953080366288\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 19963668090281374431317017250026510351550118984869870738585126468447913244591\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 17974807300702948996049252322259229942746003444136224778640009295566243156501\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 12052046477897583522878740699736101759681160588792932192885758224246430725626\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 4921034593166626300651198249205635549101612701433540517476055976860959484949\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 10185405862489710856496932329182422458788356942668474473592359869600739434412\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 5878093886505576171449048465070377785955067968838740459103515014923390639639\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 15259888626953734049577795735967576333281508824947666542918638019623811781546\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 19643669610230135658961129468905806322162637394453939877922249528939594418232\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 12224852444220822793589818921506014057813793178254991680570188956045824616826\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 6641963433101155753834035944397107424954075034582038862756599997819459513127\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 3589782713125700501109156506560851754947305163593203470270968608024453926281\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 12330486534063835148740124350008103247243211222952306312071501975705307117092\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 20509504091296584456523257770792088853619865130173628006197630419037120651742\n )\n }\n }\n}\n" + }, + "contracts/libraries/Transfer2In3Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Transfer2In3Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 32768)\n // num of public inputs\n mstore(add(vk, 0x20), 32)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 11238918059962060895836660665905685183821438171673788872298187887301460117949\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 10312536098428436059770058647883007948230826032311055958980103002216444398029\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 3069296210454062532812049058888182398466997742713116483712055777740542557095\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 10585452901889142818220136732592206035573929406563129602198941778025261934559\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 49796010413150322443747223871067686918728570624660232645490911700120682624\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 19418979289570937603858876101332413214999751685423780259104815571219376501897\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 5017549683124968830897329522528615084825569869584518140023215913256996665369\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 6904459746270415738591583761210331008369254540754508554401155557939093240173\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 15294346261666962115813163162624127728984137808463913539428567756274357657589\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 6335459220235140110171052568798094575702073047123843498885605762024671566976\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 3447729854865352811909348476580581256116229886577313169808953699321178547567\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 10391923178665150678480226437763860904879593811452327022884721625331046561649\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 21331037483834702908326522885638199264097608653827628146912836859219217391521\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 17700979571500030343918100715185217716266526246917146097813330984808052588149\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 19231315187566819499805706567670055518295048760424962411545826184537652443122\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 1786951957014031658307434161704132339929023647859863721152324287915947831283\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 891318259297166657950777135402426115367536796891436125685210585889035809375\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 19080042747384460176894767057995469942920956949014313980914237214240134307208\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 8600864573298799022763786653218006387353791810267845686055695121259061041328\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 16693779427169671344028720673356223282089909563990595319572224701304611776922\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 9157681660736307225301034938839156685740016704526090406950858434609030225480\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 8030757918449598333025173041225419314601924784825356372892442933863889091921\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 13640927194155719878577037989318164230713264172921393074620679102349279698839\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 6900604409783116559678606532527525488965021296050678826316410961047810748517\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 5252746067177671060986834545182465389119363624955154280966570801582394785840\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 9195131821976884258765963928166452788332100806625752840914173681395711439614\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 14977645969508065057243931947507598769856801213808952261859994787935726005589\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 5096294777527669951530261927053173270421982090354495165464932330992574194565\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 3545567189598828405425832938456307851398759232755240447556204001745014820301\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 1941523779920680020402590579224743136261147114116204389037553310789640138016\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 18752226702425153987309996103585848095327330331398325134534482624274124156372\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 11041340585339071070596363521057299677913989755036511157364732122494432877984\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 14590850366538565268612154711126247437677807588903705071677135475079401886274\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 18590050088847501728340953044790139366495591524471631048198965975345765148219\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 21704590671982347430816904792389667189857927953663414983186296915645026530922\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 20891693206558394293557033642999941159043782671912221870570329299710569824990\n )\n }\n }\n}\n" + }, + "contracts/libraries/Transfer3In3Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Transfer3In3Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 65536)\n // num of public inputs\n mstore(add(vk, 0x20), 45)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 6745569324574292840123998773726184666805725845966057344477780763812378175216\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 15674359264100532117390420549335759541287602785521062799291583384533749901741\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 3882047939060472482494153851462770573213675187290765799393847015027127043523\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 7630821036627726874781987389422412327209162597154025595018731571961516169947\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 21225224708013383300469954369858606000505504678178518510917526718672976749965\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 16365929799382131762072204211493784381011606251973921052275294268694891754790\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 18816028553810513067728270242942259651783354986329945635353859047149476279687\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 11882680851945303658063593837716037756293837416752296611477056121789431777064\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 21510097154791711734296287821852281209791416779989865544015434367940075374914\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 3430102751397774877173034066414871678821827985103146314887340992082993984329\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 19869597504326919094166107694290620558808748604476313005465666228287903414344\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 7150111322568846997819037419437132637225578315562663408823282538527304893394\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 15160992848460929858090744745540508270198264712727437471403260552347088002356\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 14658479685250391207452586531545916785099257310771621120220342224985727703397\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 8235204123369855002620633544318875073465201482729570929826842086900101734240\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 1315782571791013709741742522230010040948540142932666264718230624795003912658\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 7021080634443416008459948952678027962506306501245829421538884411847588184010\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 6584493294015254847476792897094566004873857428175399671267891995703671301938\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 19199743165408884046745846028664619315169170959180153012829728401858950581623\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 14838749009602762930836652487207610572239367359059811743491751753845995666312\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 10248259393969855960972127876087560001222739594880062140977367664638629457979\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 3405469462517204071666729973707416410254082166076974198995581327928518673875\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 9259807925511910228709408577417518144465439748546649497440413244416264053909\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 4349742126987923639436565898601499377373071260693932114899380098788981806520\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 195924708408078159303893377539882303047203274957430754688974876101940076523\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 2730242103617344574903225508726280194241425124842703262405260488972083367491\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 20219387287202350426068670038890996732790822982376234641416083193417653609683\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 4712902992473903996354956065401616044154872569903741964754702810524685939510\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 20606018511516306199576247848201856706631620007530428100607004704631466340548\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 3431535724436156106895017518971445784357440465218022981124980111332355382620\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 16926802729258759088538388518776752987858809292908095720269836387951179849328\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 17982233223518308144739071673627895392237126231063756253762501987899411496611\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 2769108222659962988853179530681878069454558991374977224908414446449310780711\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 1229799452453481995415811771099188864368739763357472273935665649735041438448\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 4813470345909172814186147928188285492437945113396806975178500704379725081570\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 5911983361843136694947821727682990071782684402361679071602671084421707986423\n )\n }\n }\n}\n" + }, + "contracts/libraries/Mint1In2Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Mint1In2Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 16384)\n // num of public inputs\n mstore(add(vk, 0x20), 22)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 18715857233450097233566665862469612667705408112918632327151254517366615510853\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 12056659507165533739511169991607046566607546589228993432633519678105063191994\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 14824195002671574468331715635494727121571793218927771429557442195822888294112\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 15545363005844852395434066542267547241977074468438704526560481952507920680442\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 12730937992652390663908670084945912580250489721157445258662047611384656062589\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 13922972325643955705903067190275250069235823502347080251607855678412413832655\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 11205515283341717493374802581094446196264159623530455592177314841729924213298\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 21626228139140341994554265888140425084500331880890693761295353772893134873176\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 1297892505212470170669591175924901147071008882331974691087297632739019966869\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 5046998337256619649328073625306172605427225136111531257681027197976756517579\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 3416126502361838053757816729968531801453964981226124461039874315717193603949\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 13457539169423794765649307630863376252412201646715715024708233511728175887361\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 14560725448400229197269899568322480538530865768296597131421754928016376186765\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 948706310326485520368947730671484733882983133515374382612890953953178516965\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 3629576662585230443325226017156907801568659344982452092584030101519414013585\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 11755059153403672321764085695058203755528587063932979109812536973510125660021\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 11004655709419206490244680738164512138236779409731663166100876015592834374329\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 3075086625849477481019461602494583874758896233088021555313650923393327170396\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 5116214943488395672472205024247672892505731883467355177124324350502474270399\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 5862627121952215177093377764664762757373132220173512585597211838016077936314\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 17591159830764396623974345916017368127032492198578190405514161605820133619635\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 21823861194811124564815272373053730365073236057851878678286985577859771922838\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 4270340305067371269951830198578603793146745643909898988425564374444309637164\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 3429516859933338020020014748205944416226065682096817012737681215798779959358\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 18140449432973717159678873762584078749849242918610972566667541337332136871548\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 9496973080403650076452512345486781056144944295333639818676842964799046293494\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 2679601553769052076036509170798838073426403353317218807312666276919478214029\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 8104020893469546307958011379600482565107943832349081304458473817724197756534\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 15359849857211682094089890949757251089555853826462724721381029431330976452771\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 16491566299722544741678927866350154870498939946959249271831955257228312538659\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 12100931690223724084472313998885551549102209045806672061992493151022394323721\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 789632069622495739311692844331711309820973570859008137449744966665497183364\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 9372499437356245507830218065264333778849228240985893278867565670067559001476\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 5071314442263159884139201702429590502916613589463313571011317767821015131114\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 13714688610643446356217590887080562811494820054657712165894734861828853586333\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 1823119861575201921550763026703044012616621870847156108104965194178825195245\n )\n }\n }\n}\n" + }, + "contracts/libraries/Freeze2In2Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Freeze2In2Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 32768)\n // num of public inputs\n mstore(add(vk, 0x20), 7)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 5118137774697846205332813764527928981094534629179826197661885163309718792664\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 21444510867008360096097791654924066970628086592132286765149218644570218218958\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 8803078987858664729272498900762799875194584982758288268215987493230494163132\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 2433303804972293717223914306424233027859258355453999879123493306111951897773\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 3260803333275595200572169884988811547059839215101652317716205725226978273005\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 3613466037895382109608881276133312019690204476510004381563636709063308697093\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 2899439069156777615431510251772750434873724497570948892914993632800602868003\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 8379069052308825781842073463279139505822176676050290986587894691217284563176\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 11732815069861807091165298838511758216456754114248634732985660813617441774658\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 13166648630773672378735632573860809427570624939066078822309995911184719468349\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 3491113372305405096734724369052497193940883294098266073462122391919346338715\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 9827940866231584614489847721346069816554104560301469101889136447541239075558\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 13435736629650136340196094187820825115318808951343660439499146542480924445056\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 17982003639419860944219119425071532203644939147988825284644182004036282633420\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 9420441314344923881108805693844267870391289724837370305813596950535269618889\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 14052028114719021167053334693322209909986772869796949309216011765205181071250\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 5993794253539477186956400554691260472169114800994727061541419240125118730670\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 7932960467420473760327919608797843731121974235494949218022535850994096308221\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 20429406452243707916630058273965650451352739230543746812138739882954609124362\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 19692763177526054221606086118119451355223254880919552106296824049356634107628\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 5116116081275540865026368436909879211124168610156815899416152073819842308833\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 19842614482623746480218449373220727139999815807703100436601033251034509288020\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 3222495709067365879961349438698872943831082393186134710609177690951286365439\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 3703532585269560394637679600890000571417416525562741673639173852507841008896\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 14390471925844384916287376853753782482889671388409569687933776522892272411453\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 12261059506574689542871751331715340905672203590996080541963527436628201655551\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 212133813390818941086614328570019936880884093617125797928913969643819686094\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 2058275687345409085609950154451527352761528547310163982911053914079075244754\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 7507728187668840967683000771945777493711131652056583548804845913578647015848\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 15764897865018924692970368330703479768257677759902236501992745661340099646248\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 18302496468173370667823199324779836313672317342261283918121073083547306893947\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 8286815911028648157724790867291052312955947067988434001008620797971639607610\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 3470304694844212768511296992238419575123994956442939632524758781128057967608\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 9660892985889164184033149081062412611630238705975373538019042544308335432760\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 2964316839877400858567376484261923751031240259689039666960763176068018735519\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 12811532772714855857084788747474913882317963037829729036129619334772557515102\n )\n }\n }\n}\n" + }, + "contracts/libraries/Freeze3In3Out24DepthVk.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\n// NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-libraries --release`.\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport \"./BN254.sol\";\n\nlibrary Freeze3In3Out24DepthVk {\n function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {\n assembly {\n // domain size\n mstore(vk, 32768)\n // num of public inputs\n mstore(add(vk, 0x20), 9)\n\n // sigma0\n mstore(\n mload(add(vk, 0x40)),\n 13960731824189571867091334541157339805012676983241098249236778497915465352053\n )\n mstore(\n add(mload(add(vk, 0x40)), 0x20),\n 15957967148909612161116218663566087497068811688498797226467515095325657152045\n )\n // sigma1\n mstore(\n mload(add(vk, 0x60)),\n 10072587287838607559866316765624459623039578259829899225485734337870604479821\n )\n mstore(\n add(mload(add(vk, 0x60)), 0x20),\n 15609102652788964903340031795269302405421393375766454476378251576322947285858\n )\n // sigma2\n mstore(\n mload(add(vk, 0x80)),\n 6565707169634610873662073730120423414251877113110818166564470784428289496576\n )\n mstore(\n add(mload(add(vk, 0x80)), 0x20),\n 9611712776953584296612678707999788907754017999002246476393974258810867124564\n )\n // sigma3\n mstore(\n mload(add(vk, 0xa0)),\n 19122400063214294010991425447556532201595762243736666161415050184531098654161\n )\n mstore(\n add(mload(add(vk, 0xa0)), 0x20),\n 8531074110951311734071734321378003618052738734286317677359289798683215129985\n )\n // sigma4\n mstore(\n mload(add(vk, 0xc0)),\n 18914674706112982859579196036464470962561796494057486369943014188445892675591\n )\n mstore(\n add(mload(add(vk, 0xc0)), 0x20),\n 8521550178820292984099911306615540388090622911114862049753515592863829430736\n )\n\n // q1\n mstore(\n mload(add(vk, 0xe0)),\n 14630335835391046544786473024276900306274085179180854494149987003151236405693\n )\n mstore(\n add(mload(add(vk, 0xe0)), 0x20),\n 11927636740621831793456799535735389934490350641107279163802406976389995490906\n )\n // q2\n mstore(\n mload(add(vk, 0x100)),\n 12724914112829888521503996001370933887413324349676112061904353298191125761834\n )\n mstore(\n add(mload(add(vk, 0x100)), 0x20),\n 3433370683786676509006167821257247081483834358490691629467376279251656650897\n )\n // q3\n mstore(\n mload(add(vk, 0x120)),\n 9566744544381523978155846140753126684369534823789897373672815695046810310988\n )\n mstore(\n add(mload(add(vk, 0x120)), 0x20),\n 260017699035964770662690666115311602214922546306804012310168827438556483441\n )\n // q4\n mstore(\n mload(add(vk, 0x140)),\n 18742890127040989288898023133652949889864689947035150783791742574000686319400\n )\n mstore(\n add(mload(add(vk, 0x140)), 0x20),\n 18749161983189150319356152659011703669863797011859087161475368338926038180308\n )\n\n // qM12\n mstore(\n mload(add(vk, 0x160)),\n 20773233313791930222139945008080890514898946888819625041024291924369611870607\n )\n mstore(\n add(mload(add(vk, 0x160)), 0x20),\n 13521724424975535658347353167027580945107539483287924982357298371687877483981\n )\n // qM34\n mstore(\n mload(add(vk, 0x180)),\n 10660982607928179139814177842882617778440401746692506684983260589289268170379\n )\n mstore(\n add(mload(add(vk, 0x180)), 0x20),\n 15139413484465466645149010003574654339361200137557967877891360282092282891685\n )\n\n // qO\n mstore(\n mload(add(vk, 0x1a0)),\n 17250558007005834955604250406579207360748810924758511953913092810009135851470\n )\n mstore(\n add(mload(add(vk, 0x1a0)), 0x20),\n 11258418978437321501318046240697776859180107275977030400553604411488978149668\n )\n // qC\n mstore(\n mload(add(vk, 0x1c0)),\n 18952078950487788846193130112459018587473354670050028821020889375362878213321\n )\n mstore(\n add(mload(add(vk, 0x1c0)), 0x20),\n 17193026626593699161155564126784943150078109362562131961513990003707313130311\n )\n // qH1\n mstore(\n mload(add(vk, 0x1e0)),\n 14543481681504505345294846715453463092188884601462120536722150134676588633429\n )\n mstore(\n add(mload(add(vk, 0x1e0)), 0x20),\n 18051927297986484527611703191585266713528321784715802343699150271856051244721\n )\n // qH2\n mstore(\n mload(add(vk, 0x200)),\n 17183091890960203175777065490726876011944304977299231686457191186480347944964\n )\n mstore(\n add(mload(add(vk, 0x200)), 0x20),\n 4490401529426574565331238171714181866458606184922225399124187058005801778892\n )\n // qH3\n mstore(\n mload(add(vk, 0x220)),\n 1221754396433704762941109064372027557900417150628742839724350141274324105531\n )\n mstore(\n add(mload(add(vk, 0x220)), 0x20),\n 5852202975250895807153833762470523277935452126865915206223172229093142057204\n )\n // qH4\n mstore(\n mload(add(vk, 0x240)),\n 15942219407079940317108327336758085920828255563342347502490598820248118460133\n )\n mstore(\n add(mload(add(vk, 0x240)), 0x20),\n 13932908789216121516788648116401360726086794781411868046768741292235436938527\n )\n // qEcc\n mstore(\n mload(add(vk, 0x260)),\n 11253921189643581015308547816247612243572238063440388125238308675751100437670\n )\n mstore(\n add(mload(add(vk, 0x260)), 0x20),\n 21538818198962061056994656088458979220103547193654086011201760604068846580076\n )\n }\n }\n}\n" + }, + "contracts/mocks/TestCapeTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../CAPE.sol\";\nimport \"../interfaces/IPlonkVerifier.sol\";\n\ncontract TestCapeTypes {\n function checkNullifier(uint256 nf) public pure returns (uint256) {\n return nf;\n }\n\n function checkRecordCommitment(uint256 rc) public pure returns (uint256) {\n return rc;\n }\n\n function checkMerkleRoot(uint256 root) public pure returns (uint256) {\n return root;\n }\n\n function checkForeignAssetCode(uint256 code) public pure returns (uint256) {\n return code;\n }\n\n function checkAssetPolicy(CAPE.AssetPolicy memory policy)\n public\n pure\n returns (CAPE.AssetPolicy memory)\n {\n return policy;\n }\n\n function checkAssetDefinition(CAPE.AssetDefinition memory def)\n public\n pure\n returns (CAPE.AssetDefinition memory)\n {\n return def;\n }\n\n function checkRecordOpening(CAPE.RecordOpening memory ro)\n public\n pure\n returns (CAPE.RecordOpening memory)\n {\n return ro;\n }\n\n function checkPlonkProof(IPlonkVerifier.PlonkProof memory proof)\n public\n pure\n returns (IPlonkVerifier.PlonkProof memory)\n {\n return proof;\n }\n\n function checkAuditMemo(CAPE.AuditMemo memory memo)\n public\n pure\n returns (CAPE.AuditMemo memory)\n {\n return memo;\n }\n\n function checkNoteType(CAPE.NoteType t) public pure returns (CAPE.NoteType) {\n return t;\n }\n\n function checkMintNote(CAPE.MintNote memory note) public pure returns (CAPE.MintNote memory) {\n return note;\n }\n\n function checkFreezeNote(CAPE.FreezeNote memory note)\n public\n pure\n returns (CAPE.FreezeNote memory)\n {\n return note;\n }\n\n function checkBurnNote(CAPE.BurnNote memory note) public pure returns (CAPE.BurnNote memory) {\n return note;\n }\n\n function checkTransferNote(CAPE.TransferNote memory note)\n public\n pure\n returns (CAPE.TransferNote memory)\n {\n return note;\n }\n\n function checkCapeBlock(CAPE.CapeBlock memory b) public pure returns (CAPE.CapeBlock memory) {\n return b;\n }\n}\n" + }, + "contracts/mocks/TestVerifyingKeys.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {VerifyingKeys as Vk} from \"../libraries/VerifyingKeys.sol\";\nimport \"../interfaces/IPlonkVerifier.sol\";\n\ncontract TestVerifyingKeys {\n function getVkById(uint256 encodedId)\n public\n pure\n returns (IPlonkVerifier.VerifyingKey memory)\n {\n return Vk.getVkById(encodedId);\n }\n\n function getEncodedId(\n uint8 noteType,\n uint8 numInput,\n uint8 numOutput,\n uint8 treeDepth\n ) public pure returns (uint256 encodedId) {\n return Vk.getEncodedId(noteType, numInput, numOutput, treeDepth);\n }\n}\n" + }, + "contracts/mocks/TestTranscript.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"hardhat/console.sol\";\n\nimport {BN254} from \"../libraries/BN254.sol\";\nimport {Transcript} from \"../verifier/Transcript.sol\";\nimport {IPlonkVerifier} from \"../interfaces/IPlonkVerifier.sol\";\n\ncontract TestTranscript {\n using Transcript for Transcript.TranscriptData;\n\n function appendMessage(Transcript.TranscriptData memory transcript, bytes memory message)\n public\n pure\n returns (Transcript.TranscriptData memory)\n {\n transcript.appendMessage(message);\n return transcript;\n }\n\n function appendChallenge(Transcript.TranscriptData memory transcript, uint256 challenge)\n public\n pure\n returns (Transcript.TranscriptData memory)\n {\n transcript.appendChallenge(challenge);\n return transcript;\n }\n\n function getAndAppendChallenge(Transcript.TranscriptData memory transcript)\n public\n pure\n returns (uint256)\n {\n return transcript.getAndAppendChallenge();\n }\n\n function testAppendMessageAndGet(\n Transcript.TranscriptData memory transcript,\n bytes memory message\n ) public pure returns (uint256) {\n transcript.appendMessage(message);\n return transcript.getAndAppendChallenge();\n }\n\n function testAppendChallengeAndGet(\n Transcript.TranscriptData memory transcript,\n uint256 challenge\n ) public pure returns (uint256) {\n transcript.appendChallenge(challenge);\n return transcript.getAndAppendChallenge();\n }\n\n function testAppendCommitmentAndGet(\n Transcript.TranscriptData memory transcript,\n BN254.G1Point memory comm\n ) public pure returns (uint256) {\n transcript.appendCommitment(comm);\n return transcript.getAndAppendChallenge();\n }\n\n function testAppendCommitmentsAndGet(\n Transcript.TranscriptData memory transcript,\n BN254.G1Point[] memory comms\n ) public pure returns (uint256) {\n transcript.appendCommitments(comms);\n return transcript.getAndAppendChallenge();\n }\n\n function testGetAndAppendChallengeMultipleTimes(\n Transcript.TranscriptData memory transcript,\n uint256 times\n ) public pure returns (uint256 challenge) {\n for (uint256 i = 0; i < times; i++) {\n challenge = transcript.getAndAppendChallenge();\n }\n }\n\n function testAppendVkAndPubInput(\n Transcript.TranscriptData memory transcript,\n IPlonkVerifier.VerifyingKey memory verifyingKey,\n uint256[] memory pubInputs\n ) public pure returns (Transcript.TranscriptData memory) {\n transcript.appendVkAndPubInput(verifyingKey, pubInputs);\n return transcript;\n }\n\n function testAppendProofEvaluations(\n Transcript.TranscriptData memory transcript,\n IPlonkVerifier.PlonkProof memory proof\n ) public pure returns (Transcript.TranscriptData memory) {\n transcript.appendProofEvaluations(proof);\n return transcript;\n }\n}\n" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" + }, + "contracts/verifier/Transcript.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n//\n// There is currently a bug in solidity that may affect the security of the contract.\n// An patch is available for Jellyfish https://github.com/EspressoSystems/jellyfish/pull/70\n// Corresponding changes are to be made to the solidity code here.\n\npragma solidity ^0.8.0;\n\nimport \"solidity-bytes-utils/contracts/BytesLib.sol\";\nimport \"../libraries/Utils.sol\";\nimport {BN254} from \"../libraries/BN254.sol\";\nimport {IPlonkVerifier} from \"../interfaces/IPlonkVerifier.sol\";\n\nlibrary Transcript {\n struct TranscriptData {\n bytes transcript;\n bytes32[2] state;\n }\n\n // ================================\n // Primitive functions\n // ================================\n function appendMessage(TranscriptData memory self, bytes memory message) internal pure {\n self.transcript = abi.encodePacked(self.transcript, message);\n }\n\n function appendFieldElement(TranscriptData memory self, uint256 fieldElement) internal pure {\n appendMessage(self, abi.encodePacked(Utils.reverseEndianness(fieldElement)));\n }\n\n function appendGroupElement(TranscriptData memory self, BN254.G1Point memory comm)\n internal\n pure\n {\n bytes memory commBytes = BN254.g1Serialize(comm);\n appendMessage(self, commBytes);\n }\n\n // ================================\n // Transcript APIs\n // ================================\n function appendChallenge(TranscriptData memory self, uint256 challenge) internal pure {\n appendFieldElement(self, challenge);\n }\n\n function appendCommitments(TranscriptData memory self, BN254.G1Point[] memory comms)\n internal\n pure\n {\n for (uint256 i = 0; i < comms.length; i++) {\n appendCommitment(self, comms[i]);\n }\n }\n\n function appendCommitment(TranscriptData memory self, BN254.G1Point memory comm)\n internal\n pure\n {\n appendGroupElement(self, comm);\n }\n\n function getAndAppendChallenge(TranscriptData memory self) internal pure returns (uint256) {\n bytes32 h1 = keccak256(\n abi.encodePacked(self.state[0], self.state[1], self.transcript, uint8(0))\n );\n bytes32 h2 = keccak256(\n abi.encodePacked(self.state[0], self.state[1], self.transcript, uint8(1))\n );\n\n self.state[0] = h1;\n self.state[1] = h2;\n\n return BN254.fromLeBytesModOrder(BytesLib.slice(abi.encodePacked(h1, h2), 0, 48));\n }\n\n /// @dev Append the verifying key and the public inputs to the transcript.\n /// @param verifyingKey verifiying key\n /// @param publicInput a list of field elements\n function appendVkAndPubInput(\n TranscriptData memory self,\n IPlonkVerifier.VerifyingKey memory verifyingKey,\n uint256[] memory publicInput\n ) internal pure {\n uint64 sizeInBits = 254;\n\n // Fr field size in bits\n appendMessage(\n self,\n BytesLib.slice(abi.encodePacked(Utils.reverseEndianness(sizeInBits)), 0, 8)\n );\n\n // domain size\n appendMessage(\n self,\n BytesLib.slice(\n abi.encodePacked(Utils.reverseEndianness(verifyingKey.domainSize)),\n 0,\n 8\n )\n );\n\n // number of inputs\n appendMessage(\n self,\n BytesLib.slice(abi.encodePacked(Utils.reverseEndianness(verifyingKey.numInputs)), 0, 8)\n );\n\n // =====================\n // k: coset representatives\n // =====================\n // Currently, K is hardcoded, and there are 5 of them since\n // # wire types == 5\n appendFieldElement(self, 0x1); // k0 = 1\n appendFieldElement(\n self,\n 0x2f8dd1f1a7583c42c4e12a44e110404c73ca6c94813f85835da4fb7bb1301d4a\n ); // k1\n appendFieldElement(\n self,\n 0x1ee678a0470a75a6eaa8fe837060498ba828a3703b311d0f77f010424afeb025\n ); // k2\n appendFieldElement(\n self,\n 0x2042a587a90c187b0a087c03e29c968b950b1db26d5c82d666905a6895790c0a\n ); // k3\n appendFieldElement(\n self,\n 0x2e2b91456103698adf57b799969dea1c8f739da5d8d40dd3eb9222db7c81e881\n ); // k4\n\n // selectors\n appendGroupElement(self, verifyingKey.q1);\n appendGroupElement(self, verifyingKey.q2);\n appendGroupElement(self, verifyingKey.q3);\n appendGroupElement(self, verifyingKey.q4);\n appendGroupElement(self, verifyingKey.qM12);\n appendGroupElement(self, verifyingKey.qM34);\n appendGroupElement(self, verifyingKey.qH1);\n appendGroupElement(self, verifyingKey.qH2);\n appendGroupElement(self, verifyingKey.qH3);\n appendGroupElement(self, verifyingKey.qH4);\n appendGroupElement(self, verifyingKey.qO);\n appendGroupElement(self, verifyingKey.qC);\n appendGroupElement(self, verifyingKey.qEcc);\n\n // sigmas\n appendGroupElement(self, verifyingKey.sigma0);\n appendGroupElement(self, verifyingKey.sigma1);\n appendGroupElement(self, verifyingKey.sigma2);\n appendGroupElement(self, verifyingKey.sigma3);\n appendGroupElement(self, verifyingKey.sigma4);\n\n // public inputs\n for (uint256 i = 0; i < publicInput.length; i++) {\n appendFieldElement(self, publicInput[i]);\n }\n }\n\n /// @dev Append the proof to the transcript.\n function appendProofEvaluations(\n TranscriptData memory self,\n IPlonkVerifier.PlonkProof memory proof\n ) internal pure {\n appendFieldElement(self, proof.wireEval0);\n appendFieldElement(self, proof.wireEval1);\n appendFieldElement(self, proof.wireEval2);\n appendFieldElement(self, proof.wireEval3);\n appendFieldElement(self, proof.wireEval4);\n\n appendFieldElement(self, proof.sigmaEval0);\n appendFieldElement(self, proof.sigmaEval1);\n appendFieldElement(self, proof.sigmaEval2);\n appendFieldElement(self, proof.sigmaEval3);\n\n appendFieldElement(self, proof.prodPermZetaOmegaEval);\n }\n}\n" + }, + "contracts/mocks/TestEdOnBN254.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {EdOnBN254 as C} from \"../libraries/EdOnBN254.sol\";\n\ncontract TestEdOnBN254 {\n constructor() {}\n\n function serialize(C.EdOnBN254Point memory p) public pure returns (bytes memory res) {\n return C.serialize(p);\n }\n\n function checkEdOnBn254Point(C.EdOnBN254Point memory p)\n public\n pure\n returns (C.EdOnBN254Point memory)\n {\n return p;\n }\n}\n" + }, + "contracts/verifier/PlonkVerifier.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {BN254} from \"../libraries/BN254.sol\";\nimport \"../interfaces/IPlonkVerifier.sol\";\nimport {PolynomialEval as Poly} from \"../libraries/PolynomialEval.sol\";\nimport \"./Transcript.sol\";\n\ncontract PlonkVerifier is IPlonkVerifier {\n using Transcript for Transcript.TranscriptData;\n\n // _COSET_K0 = 1, has no effect during multiplication, thus avoid declaring it here.\n uint256 private constant _COSET_K1 =\n 0x2f8dd1f1a7583c42c4e12a44e110404c73ca6c94813f85835da4fb7bb1301d4a;\n uint256 private constant _COSET_K2 =\n 0x1ee678a0470a75a6eaa8fe837060498ba828a3703b311d0f77f010424afeb025;\n uint256 private constant _COSET_K3 =\n 0x2042a587a90c187b0a087c03e29c968b950b1db26d5c82d666905a6895790c0a;\n uint256 private constant _COSET_K4 =\n 0x2e2b91456103698adf57b799969dea1c8f739da5d8d40dd3eb9222db7c81e881;\n\n // Parsed from Aztec's Ignition CRS,\n // `beta_h` \\in G2 where \\beta is the trapdoor, h is G2 generator `BN254.P2()`\n // See parsing code: https://github.com/alxiong/crs\n BN254.G2Point private _betaH =\n BN254.G2Point({\n x0: 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1,\n x1: 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0,\n y0: 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4,\n y1: 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55\n });\n\n /// The number of wire types of the circuit, TurboPlonk has 5.\n uint256 private constant _NUM_WIRE_TYPES = 5;\n\n /// @dev polynomial commitment evaluation info.\n struct PcsInfo {\n // a random combiner that was used to combine evaluations at point\n uint256 u; // 0x00\n // the point to be evaluated at\n uint256 evalPoint; // 0x20\n // the shifted point to be evaluated at\n uint256 nextEvalPoint; // 0x40\n // the polynomial evaluation value\n uint256 eval; // 0x60\n // scalars of poly comm for MSM\n uint256[] commScalars; // 0x80\n // bases of poly comm for MSM\n BN254.G1Point[] commBases; // 0xa0\n // proof of evaluations at point `eval_point`\n BN254.G1Point openingProof; // 0xc0\n // proof of evaluations at point `next_eval_point`\n BN254.G1Point shiftedOpeningProof; // 0xe0\n }\n\n /// @dev Plonk IOP verifier challenges.\n struct Challenges {\n uint256 alpha; // 0x00\n uint256 alpha2; // 0x20\n uint256 alpha3; // 0x40\n uint256 beta; // 0x60\n uint256 gamma; // 0x80\n uint256 zeta; // 0xA0\n uint256 v; // 0xC0\n uint256 u; // 0xE0\n }\n\n /// @dev Batch verify multiple TurboPlonk proofs.\n /// @param verifyingKeys An array of verifier keys\n /// @param publicInputs A two-dimensional array of public inputs.\n /// @param proofs An array of Plonk proofs\n /// @param extraTranscriptInitMsgs An array of bytes from\n /// transcript initialization messages\n function batchVerify(\n VerifyingKey[] memory verifyingKeys,\n uint256[][] memory publicInputs,\n PlonkProof[] memory proofs,\n bytes[] memory extraTranscriptInitMsgs\n ) external view returns (bool) {\n require(\n verifyingKeys.length == proofs.length &&\n publicInputs.length == proofs.length &&\n extraTranscriptInitMsgs.length == proofs.length,\n \"Plonk: invalid input param\"\n );\n require(proofs.length > 0, \"Plonk: need at least 1 proof\");\n\n PcsInfo[] memory pcsInfos = new PcsInfo[](proofs.length);\n for (uint256 i = 0; i < proofs.length; i++) {\n // validate proofs are proper group/field elements\n _validateProof(proofs[i]);\n // validate public input are all proper scalar fields\n for (uint256 j = 0; j < publicInputs[i].length; j++) {\n BN254.validateScalarField(publicInputs[i][j]);\n }\n // prepare pcs info\n pcsInfos[i] = _preparePcsInfo(\n verifyingKeys[i],\n publicInputs[i],\n proofs[i],\n extraTranscriptInitMsgs[i]\n );\n }\n\n return _batchVerifyOpeningProofs(pcsInfos);\n }\n\n /// @dev Validate all group points and scalar fields. Revert if\n /// any are invalid.\n /// @param proof A Plonk proof\n function _validateProof(PlonkProof memory proof) internal pure {\n BN254.validateG1Point(proof.wire0);\n BN254.validateG1Point(proof.wire1);\n BN254.validateG1Point(proof.wire2);\n BN254.validateG1Point(proof.wire3);\n BN254.validateG1Point(proof.wire4);\n BN254.validateG1Point(proof.prodPerm);\n BN254.validateG1Point(proof.split0);\n BN254.validateG1Point(proof.split1);\n BN254.validateG1Point(proof.split2);\n BN254.validateG1Point(proof.split3);\n BN254.validateG1Point(proof.split4);\n BN254.validateG1Point(proof.zeta);\n BN254.validateScalarField(proof.wireEval0);\n BN254.validateScalarField(proof.wireEval1);\n BN254.validateScalarField(proof.wireEval2);\n BN254.validateScalarField(proof.wireEval3);\n BN254.validateScalarField(proof.wireEval4);\n BN254.validateScalarField(proof.sigmaEval0);\n BN254.validateScalarField(proof.sigmaEval1);\n BN254.validateScalarField(proof.sigmaEval2);\n BN254.validateScalarField(proof.sigmaEval3);\n BN254.validateScalarField(proof.prodPermZetaOmegaEval);\n }\n\n function _preparePcsInfo(\n VerifyingKey memory verifyingKey,\n uint256[] memory publicInput,\n PlonkProof memory proof,\n bytes memory extraTranscriptInitMsg\n ) internal view returns (PcsInfo memory res) {\n require(publicInput.length == verifyingKey.numInputs, \"Plonk: wrong verifying key\");\n\n Challenges memory chal = _computeChallenges(\n verifyingKey,\n publicInput,\n proof,\n extraTranscriptInitMsg\n );\n\n Poly.EvalDomain memory domain = Poly.newEvalDomain(verifyingKey.domainSize);\n // pre-compute evaluation data\n Poly.EvalData memory evalData = Poly.evalDataGen(domain, chal.zeta, publicInput);\n\n // compute opening proof in poly comm.\n uint256[] memory commScalars = new uint256[](30);\n BN254.G1Point[] memory commBases = new BN254.G1Point[](30);\n\n uint256 eval = _prepareOpeningProof(\n verifyingKey,\n evalData,\n proof,\n chal,\n commScalars,\n commBases\n );\n\n uint256 zeta = chal.zeta;\n uint256 omega = domain.groupGen;\n uint256 p = BN254.R_MOD;\n uint256 zetaOmega;\n assembly {\n zetaOmega := mulmod(zeta, omega, p)\n }\n\n res = PcsInfo(\n chal.u,\n zeta,\n zetaOmega,\n eval,\n commScalars,\n commBases,\n proof.zeta,\n proof.zetaOmega\n );\n }\n\n function _computeChallenges(\n VerifyingKey memory verifyingKey,\n uint256[] memory publicInput,\n PlonkProof memory proof,\n bytes memory extraTranscriptInitMsg\n ) internal pure returns (Challenges memory res) {\n Transcript.TranscriptData memory transcript;\n uint256 p = BN254.R_MOD;\n\n transcript.appendMessage(extraTranscriptInitMsg);\n transcript.appendVkAndPubInput(verifyingKey, publicInput);\n transcript.appendGroupElement(proof.wire0);\n transcript.appendGroupElement(proof.wire1);\n transcript.appendGroupElement(proof.wire2);\n transcript.appendGroupElement(proof.wire3);\n transcript.appendGroupElement(proof.wire4);\n\n // have to compute tau, but not really used anywhere\n // slither-disable-next-line unused-return\n transcript.getAndAppendChallenge();\n res.beta = transcript.getAndAppendChallenge();\n res.gamma = transcript.getAndAppendChallenge();\n\n transcript.appendGroupElement(proof.prodPerm);\n\n res.alpha = transcript.getAndAppendChallenge();\n\n transcript.appendGroupElement(proof.split0);\n transcript.appendGroupElement(proof.split1);\n transcript.appendGroupElement(proof.split2);\n transcript.appendGroupElement(proof.split3);\n transcript.appendGroupElement(proof.split4);\n\n res.zeta = transcript.getAndAppendChallenge();\n\n transcript.appendProofEvaluations(proof);\n res.v = transcript.getAndAppendChallenge();\n\n transcript.appendGroupElement(proof.zeta);\n transcript.appendGroupElement(proof.zetaOmega);\n res.u = transcript.getAndAppendChallenge();\n\n assembly {\n let alpha := mload(res)\n let alpha2 := mulmod(alpha, alpha, p)\n let alpha3 := mulmod(alpha2, alpha, p)\n mstore(add(res, 0x20), alpha2)\n mstore(add(res, 0x40), alpha3)\n }\n }\n\n /// @dev Compute the constant term of the linearization polynomial.\n /// ```\n /// r_plonk = PI - L1(x) * alpha^2 - alpha * \\prod_i=1..m-1 (w_i + beta * sigma_i + gamma) * (w_m + gamma) * z(xw)\n /// ```\n /// where m is the number of wire types.\n function _computeLinPolyConstantTerm(\n Challenges memory chal,\n PlonkProof memory proof,\n Poly.EvalData memory evalData\n ) internal pure returns (uint256 res) {\n uint256 p = BN254.R_MOD;\n uint256 lagrangeOneEval = evalData.lagrangeOne;\n uint256 piEval = evalData.piEval;\n uint256 perm = 1;\n\n assembly {\n let beta := mload(add(chal, 0x60))\n let gamma := mload(add(chal, 0x80))\n\n // \\prod_i=1..m-1 (w_i + beta * sigma_i + gamma)\n {\n let w0 := mload(add(proof, 0x1a0))\n let sigma0 := mload(add(proof, 0x240))\n perm := mulmod(perm, addmod(add(w0, gamma), mulmod(beta, sigma0, p), p), p)\n }\n {\n let w1 := mload(add(proof, 0x1c0))\n let sigma1 := mload(add(proof, 0x260))\n perm := mulmod(perm, addmod(add(w1, gamma), mulmod(beta, sigma1, p), p), p)\n }\n {\n let w2 := mload(add(proof, 0x1e0))\n let sigma2 := mload(add(proof, 0x280))\n perm := mulmod(perm, addmod(add(w2, gamma), mulmod(beta, sigma2, p), p), p)\n }\n {\n let w3 := mload(add(proof, 0x200))\n let sigma3 := mload(add(proof, 0x2a0))\n perm := mulmod(perm, addmod(add(w3, gamma), mulmod(beta, sigma3, p), p), p)\n }\n\n // \\prod_i=1..m-1 (w_i + beta * sigma_i + gamma) * (w_m + gamma) * z(xw)\n {\n let w4 := mload(add(proof, 0x220))\n let permNextEval := mload(add(proof, 0x2c0))\n perm := mulmod(perm, mulmod(addmod(w4, gamma, p), permNextEval, p), p)\n }\n\n let alpha := mload(chal)\n let alpha2 := mload(add(chal, 0x20))\n // PI - L1(x) * alpha^2 - alpha * \\prod_i=1..m-1 (w_i + beta * sigma_i + gamma) * (w_m + gamma) * z(xw)\n res := addmod(piEval, sub(p, mulmod(alpha2, lagrangeOneEval, p)), p)\n res := addmod(res, sub(p, mulmod(alpha, perm, p)), p)\n }\n }\n\n /// @dev Compute components in [E]1 and [F]1 used for PolyComm opening verification\n /// equivalent of JF's https://github.com/EspressoSystems/jellyfish/blob/main/plonk/src/proof_system/verifier.rs#L154-L170\n /// caller allocates the memory fr commScalars and commBases\n /// requires Arrays of size 30.\n /// @param verifyingKey A verifier key\n /// @param evalData A polynomial evaluation\n /// @param proof A Plonk proof\n /// @param chal A set of challenges\n /// @param commScalars Common scalars\n /// @param commBases Common bases\n // The returned commitment is a generalization of\n // `[F]1` described in Sec 8.4, step 10 of https://eprint.iacr.org/2019/953.pdf\n // Returned evaluation is the scalar in `[E]1` described in Sec 8.4, step 11 of https://eprint.iacr.org/2019/953.pdf\n function _prepareOpeningProof(\n VerifyingKey memory verifyingKey,\n Poly.EvalData memory evalData,\n PlonkProof memory proof,\n Challenges memory chal,\n uint256[] memory commScalars,\n BN254.G1Point[] memory commBases\n ) internal pure returns (uint256 eval) {\n // compute the constant term of the linearization polynomial\n uint256 linPolyConstant = _computeLinPolyConstantTerm(chal, proof, evalData);\n\n _preparePolyCommitments(verifyingKey, chal, evalData, proof, commScalars, commBases);\n\n eval = _prepareEvaluations(linPolyConstant, proof, commScalars);\n }\n\n /// @dev Similar to `aggregate_poly_commitments()` in Jellyfish, but we are not aggregating multiple,\n /// but rather preparing for `[F]1` from a single proof.\n /// The caller allocates the memory fr commScalars and commBases.\n /// Requires Arrays of size 30.\n function _preparePolyCommitments(\n VerifyingKey memory verifyingKey,\n Challenges memory chal,\n Poly.EvalData memory evalData,\n PlonkProof memory proof,\n uint256[] memory commScalars,\n BN254.G1Point[] memory commBases\n ) internal pure {\n _linearizationScalarsAndBases(verifyingKey, chal, evalData, proof, commBases, commScalars);\n\n uint256 p = BN254.R_MOD;\n uint256 v = chal.v;\n uint256 vBase = v;\n\n // Add wire witness polynomial commitments.\n commScalars[20] = vBase;\n commBases[20] = proof.wire0;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[21] = vBase;\n commBases[21] = proof.wire1;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[22] = vBase;\n commBases[22] = proof.wire2;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[23] = vBase;\n commBases[23] = proof.wire3;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[24] = vBase;\n commBases[24] = proof.wire4;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n // Add wire sigma polynomial commitments. The last sigma commitment is excluded.\n commScalars[25] = vBase;\n commBases[25] = verifyingKey.sigma0;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[26] = vBase;\n commBases[26] = verifyingKey.sigma1;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[27] = vBase;\n commBases[27] = verifyingKey.sigma2;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n commScalars[28] = vBase;\n commBases[28] = verifyingKey.sigma3;\n assembly {\n vBase := mulmod(vBase, v, p)\n }\n\n // Add poly commitments to be evaluated at point `zeta * g`.\n commScalars[29] = chal.u;\n commBases[29] = proof.prodPerm;\n }\n\n /// @dev `aggregate_evaluations()` in Jellyfish, but since we are not aggregating multiple, but rather preparing `[E]1` from a single proof.\n /// @dev caller allocates the memory fr commScalars\n /// requires Arrays of size 30.\n /// @param linPolyConstant A linear polynomial constant\n /// @param proof A Plonk proof\n /// @param commScalars An array of common scalars\n /// The returned value is the scalar in `[E]1` described in Sec 8.4, step 11 of https://eprint.iacr.org/2019/953.pdf\n function _prepareEvaluations(\n uint256 linPolyConstant,\n PlonkProof memory proof,\n uint256[] memory commScalars\n ) internal pure returns (uint256 eval) {\n uint256 p = BN254.R_MOD;\n assembly {\n eval := sub(p, linPolyConstant)\n for {\n let i := 0\n } lt(i, 10) {\n i := add(i, 1)\n } {\n // the first u256 stores the length of this array;\n // the next 20 elements are used to store the linearization of the scalars\n // the first free space starts from 21\n let combiner := mload(add(commScalars, mul(add(i, 21), 0x20)))\n let termEval := mload(add(proof, add(0x1a0, mul(i, 0x20))))\n eval := addmod(eval, mulmod(combiner, termEval, p), p)\n }\n }\n }\n\n /// @dev Batchly verify multiple PCS opening proofs.\n /// `open_key` has been assembled from BN254.P1(), BN254.P2() and contract variable _betaH\n /// @param pcsInfos An array of PcsInfo\n /// @dev Returns true if the entire batch verifiies and false otherwise.\n function _batchVerifyOpeningProofs(PcsInfo[] memory pcsInfos) internal view returns (bool) {\n uint256 pcsLen = pcsInfos.length;\n uint256 p = BN254.R_MOD;\n // Compute a pseudorandom challenge from the instances\n uint256 r = 1; // for a single proof, no need to use `r` (`r=1` has no effect)\n if (pcsLen > 1) {\n Transcript.TranscriptData memory transcript;\n for (uint256 i = 0; i < pcsLen; i++) {\n transcript.appendChallenge(pcsInfos[i].u);\n }\n r = transcript.getAndAppendChallenge();\n }\n\n BN254.G1Point memory a1;\n BN254.G1Point memory b1;\n\n // Compute A := A0 + r * A1 + ... + r^{m-1} * Am\n {\n uint256[] memory scalars = new uint256[](2 * pcsLen);\n BN254.G1Point[] memory bases = new BN254.G1Point[](2 * pcsLen);\n uint256 rBase = 1;\n for (uint256 i = 0; i < pcsLen; i++) {\n scalars[2 * i] = rBase;\n bases[2 * i] = pcsInfos[i].openingProof;\n\n {\n // slither-disable-next-line write-after-write\n uint256 tmp;\n uint256 u = pcsInfos[i].u;\n assembly {\n tmp := mulmod(rBase, u, p)\n }\n scalars[2 * i + 1] = tmp;\n }\n bases[2 * i + 1] = pcsInfos[i].shiftedOpeningProof;\n\n assembly {\n rBase := mulmod(rBase, r, p)\n }\n }\n a1 = BN254.multiScalarMul(bases, scalars);\n }\n\n // Compute B := B0 + r * B1 + ... + r^{m-1} * Bm\n {\n uint256[] memory scalars;\n BN254.G1Point[] memory bases;\n {\n // variable scoping to avoid \"Stack too deep\"\n uint256 scalarsLenPerInfo = pcsInfos[0].commScalars.length;\n uint256 totalScalarsLen = (2 + scalarsLenPerInfo) * pcsInfos.length + 1;\n scalars = new uint256[](totalScalarsLen);\n bases = new BN254.G1Point[](totalScalarsLen);\n }\n uint256 sumEvals = 0;\n uint256 idx = 0;\n uint256 rBase = 1;\n for (uint256 i = 0; i < pcsInfos.length; i++) {\n for (uint256 j = 0; j < pcsInfos[0].commScalars.length; j++) {\n {\n // scalars[idx] = (rBase * pcsInfos[i].commScalars[j]) % BN254.R_MOD;\n uint256 s = pcsInfos[i].commScalars[j];\n uint256 tmp;\n assembly {\n // slither-disable-next-line variable-scope\n tmp := mulmod(rBase, s, p)\n }\n scalars[idx] = tmp;\n }\n bases[idx] = pcsInfos[i].commBases[j];\n idx += 1;\n }\n\n {\n // scalars[idx] = (rBase * pcsInfos[i].evalPoint) % BN254.R_MOD;\n uint256 evalPoint = pcsInfos[i].evalPoint;\n uint256 tmp;\n assembly {\n // slither-disable-next-line variable-scope\n tmp := mulmod(rBase, evalPoint, p)\n }\n scalars[idx] = tmp;\n }\n bases[idx] = pcsInfos[i].openingProof;\n idx += 1;\n\n {\n // scalars[idx] = (rBase * pcsInfos[i].u * pcsInfos[i].nextEvalPoint) % BN254.R_MOD;\n uint256 u = pcsInfos[i].u;\n uint256 nextEvalPoint = pcsInfos[i].nextEvalPoint;\n uint256 tmp;\n assembly {\n // slither-disable-next-line variable-scope\n tmp := mulmod(rBase, mulmod(u, nextEvalPoint, p), p)\n }\n scalars[idx] = tmp;\n }\n bases[idx] = pcsInfos[i].shiftedOpeningProof;\n idx += 1;\n\n {\n // sumEvals = (sumEvals + rBase * pcsInfos[i].eval) % BN254.R_MOD;\n // rBase = (rBase * r) % BN254.R_MOD;\n uint256 eval = pcsInfos[i].eval;\n assembly {\n sumEvals := addmod(sumEvals, mulmod(rBase, eval, p), p)\n rBase := mulmod(rBase, r, p)\n }\n }\n }\n scalars[idx] = BN254.negate(sumEvals);\n bases[idx] = BN254.P1();\n b1 = BN254.negate(BN254.multiScalarMul(bases, scalars));\n }\n\n // Check e(A, [x]2) ?= e(B, [1]2)\n return BN254.pairingProd2(a1, _betaH, b1, BN254.P2());\n }\n\n /// @dev Compute the linearization of the scalars and bases.\n /// The caller allocates the memory from commScalars and commBases.\n /// Requires arrays of size 30.\n /// @param verifyingKey The verifying key\n /// @param challenge A set of challenges\n /// @param evalData Polynomial evaluation data\n /// @param proof A Plonk proof\n /// @param bases An array of BN254 G1 points\n /// @param scalars An array of scalars\n function _linearizationScalarsAndBases(\n VerifyingKey memory verifyingKey,\n Challenges memory challenge,\n Poly.EvalData memory evalData,\n PlonkProof memory proof,\n BN254.G1Point[] memory bases,\n uint256[] memory scalars\n ) internal pure {\n uint256 firstScalar;\n uint256 secondScalar;\n uint256 rhs;\n uint256 tmp;\n uint256 tmp2;\n uint256 p = BN254.R_MOD;\n\n // ============================================\n // Compute coefficient for the permutation product polynomial commitment.\n // firstScalar =\n // L1(zeta) * alpha^2\n // + alpha\n // * (beta * zeta + wireEval0 + gamma)\n // * (beta * k1 * zeta + wireEval1 + gamma)\n // * (beta * k2 * zeta + wireEval2 + gamma)\n // * ...\n // where wireEval0, wireEval1, wireEval2, ... are in w_evals\n // ============================================\n // first base and scala:\n // - proof.prodPerm\n // - firstScalar\n assembly {\n // firstScalar = alpha^2 * L1(zeta)\n firstScalar := mulmod(mload(add(challenge, 0x20)), mload(add(evalData, 0x20)), p)\n\n // rhs = alpha\n rhs := mload(challenge)\n\n // tmp = beta * zeta\n tmp := mulmod(mload(add(challenge, 0x60)), mload(add(challenge, 0xA0)), p)\n\n // =================================\n // k0 (which is 1) component\n // (beta * zeta + wireEval0 + gamma)\n // =================================\n tmp2 := addmod(tmp, mload(add(proof, 0x1A0)), p)\n tmp2 := addmod(tmp2, mload(add(challenge, 0x80)), p)\n\n rhs := mulmod(tmp2, rhs, p)\n\n // =================================\n // k1 component\n // (beta * zeta * k1 + wireEval1 + gamma)\n // =================================\n tmp2 := mulmod(tmp, _COSET_K1, p)\n tmp2 := addmod(tmp2, mload(add(proof, 0x1C0)), p)\n tmp2 := addmod(tmp2, mload(add(challenge, 0x80)), p)\n\n rhs := mulmod(tmp2, rhs, p)\n\n // =================================\n // k2 component\n // (beta * zeta * k2 + wireEval2 + gamma)\n // =================================\n tmp2 := mulmod(tmp, _COSET_K2, p)\n tmp2 := addmod(tmp2, mload(add(proof, 0x1E0)), p)\n tmp2 := addmod(tmp2, mload(add(challenge, 0x80)), p)\n rhs := mulmod(tmp2, rhs, p)\n\n // =================================\n // k3 component\n // (beta * zeta * k3 + wireEval3 + gamma)\n // =================================\n tmp2 := mulmod(tmp, _COSET_K3, p)\n tmp2 := addmod(tmp2, mload(add(proof, 0x200)), p)\n tmp2 := addmod(tmp2, mload(add(challenge, 0x80)), p)\n rhs := mulmod(tmp2, rhs, p)\n\n // =================================\n // k4 component\n // (beta * zeta * k4 + wireEval4 + gamma)\n // =================================\n tmp2 := mulmod(tmp, _COSET_K4, p)\n tmp2 := addmod(tmp2, mload(add(proof, 0x220)), p)\n tmp2 := addmod(tmp2, mload(add(challenge, 0x80)), p)\n rhs := mulmod(tmp2, rhs, p)\n\n firstScalar := addmod(firstScalar, rhs, p)\n }\n bases[0] = proof.prodPerm;\n scalars[0] = firstScalar;\n\n // ============================================\n // Compute coefficient for the last wire sigma polynomial commitment.\n // secondScalar = alpha * beta * z_w * [s_sigma_3]_1\n // * (wireEval0 + gamma + beta * sigmaEval0)\n // * (wireEval1 + gamma + beta * sigmaEval1)\n // * ...\n // ============================================\n // second base and scala:\n // - verifyingKey.sigma4\n // - secondScalar\n assembly {\n // secondScalar = alpha * beta * z_w\n secondScalar := mulmod(mload(challenge), mload(add(challenge, 0x60)), p)\n secondScalar := mulmod(secondScalar, mload(add(proof, 0x2C0)), p)\n\n // (wireEval0 + gamma + beta * sigmaEval0)\n tmp := mulmod(mload(add(challenge, 0x60)), mload(add(proof, 0x240)), p)\n tmp := addmod(tmp, mload(add(proof, 0x1A0)), p)\n tmp := addmod(tmp, mload(add(challenge, 0x80)), p)\n\n secondScalar := mulmod(secondScalar, tmp, p)\n\n // (wireEval1 + gamma + beta * sigmaEval1)\n tmp := mulmod(mload(add(challenge, 0x60)), mload(add(proof, 0x260)), p)\n tmp := addmod(tmp, mload(add(proof, 0x1C0)), p)\n tmp := addmod(tmp, mload(add(challenge, 0x80)), p)\n\n secondScalar := mulmod(secondScalar, tmp, p)\n\n // (wireEval2 + gamma + beta * sigmaEval2)\n tmp := mulmod(mload(add(challenge, 0x60)), mload(add(proof, 0x280)), p)\n tmp := addmod(tmp, mload(add(proof, 0x1E0)), p)\n tmp := addmod(tmp, mload(add(challenge, 0x80)), p)\n\n secondScalar := mulmod(secondScalar, tmp, p)\n\n // (wireEval3 + gamma + beta * sigmaEval3)\n tmp := mulmod(mload(add(challenge, 0x60)), mload(add(proof, 0x2A0)), p)\n tmp := addmod(tmp, mload(add(proof, 0x200)), p)\n tmp := addmod(tmp, mload(add(challenge, 0x80)), p)\n\n secondScalar := mulmod(secondScalar, tmp, p)\n }\n bases[1] = verifyingKey.sigma4;\n scalars[1] = p - secondScalar;\n\n // ============================================\n // next 13 are for selectors:\n //\n // the selectors are organized as\n // - q_lc\n // - q_mul\n // - q_hash\n // - q_o\n // - q_c\n // - q_ecc\n // ============================================\n\n // ============\n // q_lc\n // ============\n // q_1...q_4\n scalars[2] = proof.wireEval0;\n scalars[3] = proof.wireEval1;\n scalars[4] = proof.wireEval2;\n scalars[5] = proof.wireEval3;\n bases[2] = verifyingKey.q1;\n bases[3] = verifyingKey.q2;\n bases[4] = verifyingKey.q3;\n bases[5] = verifyingKey.q4;\n\n // ============\n // q_M\n // ============\n // q_M12 and q_M34\n // q_M12 = w_evals[0] * w_evals[1];\n assembly {\n tmp := mulmod(mload(add(proof, 0x1A0)), mload(add(proof, 0x1C0)), p)\n }\n scalars[6] = tmp;\n bases[6] = verifyingKey.qM12;\n\n assembly {\n tmp := mulmod(mload(add(proof, 0x1E0)), mload(add(proof, 0x200)), p)\n }\n scalars[7] = tmp;\n bases[7] = verifyingKey.qM34;\n\n // ============\n // q_H\n // ============\n // w_evals[0].pow([5]);\n assembly {\n tmp := mload(add(proof, 0x1A0))\n tmp2 := mulmod(tmp, tmp, p)\n tmp2 := mulmod(tmp2, tmp2, p)\n tmp := mulmod(tmp, tmp2, p)\n }\n scalars[8] = tmp;\n bases[8] = verifyingKey.qH1;\n\n // w_evals[1].pow([5]);\n assembly {\n tmp := mload(add(proof, 0x1C0))\n tmp2 := mulmod(tmp, tmp, p)\n tmp2 := mulmod(tmp2, tmp2, p)\n tmp := mulmod(tmp, tmp2, p)\n }\n scalars[9] = tmp;\n bases[9] = verifyingKey.qH2;\n\n // w_evals[2].pow([5]);\n assembly {\n tmp := mload(add(proof, 0x1E0))\n tmp2 := mulmod(tmp, tmp, p)\n tmp2 := mulmod(tmp2, tmp2, p)\n tmp := mulmod(tmp, tmp2, p)\n }\n scalars[10] = tmp;\n bases[10] = verifyingKey.qH3;\n\n // w_evals[3].pow([5]);\n assembly {\n tmp := mload(add(proof, 0x200))\n tmp2 := mulmod(tmp, tmp, p)\n tmp2 := mulmod(tmp2, tmp2, p)\n tmp := mulmod(tmp, tmp2, p)\n }\n scalars[11] = tmp;\n bases[11] = verifyingKey.qH4;\n\n // ============\n // q_o and q_c\n // ============\n // q_o\n scalars[12] = p - proof.wireEval4;\n bases[12] = verifyingKey.qO;\n // q_c\n scalars[13] = 1;\n bases[13] = verifyingKey.qC;\n\n // ============\n // q_Ecc\n // ============\n // q_Ecc = w_evals[0] * w_evals[1] * w_evals[2] * w_evals[3] * w_evals[4];\n assembly {\n tmp := mulmod(mload(add(proof, 0x1A0)), mload(add(proof, 0x1C0)), p)\n tmp := mulmod(tmp, mload(add(proof, 0x1E0)), p)\n tmp := mulmod(tmp, mload(add(proof, 0x200)), p)\n tmp := mulmod(tmp, mload(add(proof, 0x220)), p)\n }\n scalars[14] = tmp;\n bases[14] = verifyingKey.qEcc;\n\n // ============================================\n // the last 5 are for splitting quotient commitments\n // ============================================\n\n // first one is 1-zeta^n\n scalars[15] = p - evalData.vanishEval;\n bases[15] = proof.split0;\n assembly {\n // tmp = zeta^{n+2}\n tmp := addmod(mload(evalData), 1, p)\n // todo: use pre-computed zeta^2\n tmp2 := mulmod(mload(add(challenge, 0xA0)), mload(add(challenge, 0xA0)), p)\n tmp := mulmod(tmp, tmp2, p)\n }\n\n // second one is (1-zeta^n) zeta^(n+2)\n assembly {\n tmp2 := mulmod(mload(add(scalars, mul(16, 0x20))), tmp, p)\n }\n scalars[16] = tmp2;\n bases[16] = proof.split1;\n\n // third one is (1-zeta^n) zeta^2(n+2)\n assembly {\n tmp2 := mulmod(mload(add(scalars, mul(17, 0x20))), tmp, p)\n }\n scalars[17] = tmp2;\n bases[17] = proof.split2;\n\n // forth one is (1-zeta^n) zeta^3(n+2)\n assembly {\n tmp2 := mulmod(mload(add(scalars, mul(18, 0x20))), tmp, p)\n }\n scalars[18] = tmp2;\n bases[18] = proof.split3;\n\n // fifth one is (1-zeta^n) zeta^4(n+2)\n assembly {\n tmp2 := mulmod(mload(add(scalars, mul(19, 0x20))), tmp, p)\n }\n scalars[19] = tmp2;\n bases[19] = proof.split4;\n }\n}\n" + }, + "contracts/libraries/PolynomialEval.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {BN254} from \"../libraries/BN254.sol\";\n\nlibrary PolynomialEval {\n /// @dev a Radix 2 Evaluation Domain\n struct EvalDomain {\n uint256 logSize; // log_2(self.size)\n uint256 size; // Size of the domain as a field element\n uint256 sizeInv; // Inverse of the size in the field\n uint256 groupGen; // A generator of the subgroup\n uint256 groupGenInv; // Inverse of the generator of the subgroup\n }\n\n /// @dev stores vanishing poly, lagrange at 1, and Public input poly\n struct EvalData {\n uint256 vanishEval;\n uint256 lagrangeOne;\n uint256 piEval;\n }\n\n /// @dev compute the EvalData for a given domain and a challenge zeta\n function evalDataGen(\n EvalDomain memory self,\n uint256 zeta,\n uint256[] memory publicInput\n ) internal view returns (EvalData memory evalData) {\n evalData.vanishEval = evaluateVanishingPoly(self, zeta);\n evalData.lagrangeOne = evaluateLagrangeOne(self, zeta, evalData.vanishEval);\n evalData.piEval = evaluatePiPoly(self, publicInput, zeta, evalData.vanishEval);\n }\n\n /// @dev Create a new Radix2EvalDomain with `domainSize` which should be power of 2.\n /// @dev Will revert if domainSize is not among {2^14, 2^15, 2^16, 2^17}\n function newEvalDomain(uint256 domainSize) internal pure returns (EvalDomain memory) {\n if (domainSize == 16384) {\n return\n EvalDomain(\n 14,\n domainSize,\n 0x30638CE1A7661B6337A964756AA75257C6BF4778D89789AB819CE60C19B04001,\n 0x2D965651CDD9E4811F4E51B80DDCA8A8B4A93EE17420AAE6ADAA01C2617C6E85,\n 0x281C036F06E7E9E911680D42558E6E8CF40976B0677771C0F8EEE934641C8410\n );\n } else if (domainSize == 32768) {\n return\n EvalDomain(\n 15,\n domainSize,\n 0x3063edaa444bddc677fcd515f614555a777997e0a9287d1e62bf6dd004d82001,\n 0x2d1ba66f5941dc91017171fa69ec2bd0022a2a2d4115a009a93458fd4e26ecfb,\n 0x05d33766e4590b3722701b6f2fa43d0dc3f028424d384e68c92a742fb2dbc0b4\n );\n } else if (domainSize == 65536) {\n return\n EvalDomain(\n 16,\n domainSize,\n 0x30641e0e92bebef818268d663bcad6dbcfd6c0149170f6d7d350b1b1fa6c1001,\n 0x00eeb2cb5981ed45649abebde081dcff16c8601de4347e7dd1628ba2daac43b7,\n 0x0b5d56b77fe704e8e92338c0082f37e091126414c830e4c6922d5ac802d842d4\n );\n } else if (domainSize == 131072) {\n return\n EvalDomain(\n 17,\n domainSize,\n 0x30643640b9f82f90e83b698e5ea6179c7c05542e859533b48b9953a2f5360801,\n 0x1bf82deba7d74902c3708cc6e70e61f30512eca95655210e276e5858ce8f58e5,\n 0x244cf010c43ca87237d8b00bf9dd50c4c01c7f086bd4e8c920e75251d96f0d22\n );\n } else {\n revert(\"Poly: size must in 2^{14~17}\");\n }\n }\n\n // This evaluates the vanishing polynomial for this domain at zeta.\n // For multiplicative subgroups, this polynomial is\n // `z(X) = X^self.size - 1`.\n function evaluateVanishingPoly(EvalDomain memory self, uint256 zeta)\n internal\n pure\n returns (uint256 res)\n {\n uint256 p = BN254.R_MOD;\n uint256 logSize = self.logSize;\n\n assembly {\n switch zeta\n case 0 {\n res := sub(p, 1)\n }\n default {\n res := zeta\n for {\n let i := 0\n } lt(i, logSize) {\n i := add(i, 1)\n } {\n res := mulmod(res, res, p)\n }\n // since zeta != 0 we know that res is not 0\n // so we can safely do a subtraction\n res := sub(res, 1)\n }\n }\n }\n\n /// @dev Evaluate the lagrange polynomial at point `zeta` given the vanishing polynomial evaluation `vanish_eval`.\n function evaluateLagrangeOne(\n EvalDomain memory self,\n uint256 zeta,\n uint256 vanishEval\n ) internal view returns (uint256 res) {\n if (vanishEval == 0) {\n return 0;\n }\n\n uint256 p = BN254.R_MOD;\n uint256 divisor;\n uint256 vanishEvalMulSizeInv = self.sizeInv;\n\n // =========================\n // lagrange_1_eval = vanish_eval / self.size / (zeta - 1)\n // =========================\n assembly {\n vanishEvalMulSizeInv := mulmod(vanishEval, vanishEvalMulSizeInv, p)\n\n switch zeta\n case 0 {\n divisor := sub(p, 1)\n }\n default {\n divisor := sub(zeta, 1)\n }\n }\n divisor = BN254.invert(divisor);\n assembly {\n res := mulmod(vanishEvalMulSizeInv, divisor, p)\n }\n }\n\n /// @dev Evaluate public input polynomial at point `zeta`.\n function evaluatePiPoly(\n EvalDomain memory self,\n uint256[] memory pi,\n uint256 zeta,\n uint256 vanishEval\n ) internal view returns (uint256 res) {\n if (vanishEval == 0) {\n return 0;\n }\n\n uint256 p = BN254.R_MOD;\n uint256 length = pi.length;\n uint256 ithLagrange;\n uint256 ithDivisor;\n uint256 tmp;\n uint256 vanishEvalDivN = self.sizeInv;\n uint256 divisorProd;\n uint256[] memory localDomainElements = domainElements(self, length);\n uint256[] memory divisors = new uint256[](length);\n\n assembly {\n // vanish_eval_div_n = (zeta^n-1)/n\n vanishEvalDivN := mulmod(vanishEvalDivN, vanishEval, p)\n\n // Now we need to compute\n // \\sum_{i=0..l} L_{i,H}(zeta) * pub_input[i]\n // where\n // - L_{i,H}(zeta)\n // = Z_H(zeta) * v_i / (zeta - g^i)\n // = vanish_eval_div_n * g^i / (zeta - g^i)\n // - v_i = g^i / n\n //\n // we want to use batch inversion method where we compute\n //\n // divisorProd = 1 / \\prod (zeta - g^i)\n //\n // and then each 1 / (zeta - g^i) can be computed via (length - 1)\n // multiplications:\n //\n // 1 / (zeta - g^i) = divisorProd * \\prod_{j!=i} (zeta - g^j)\n //\n // In total this takes n(n-1) multiplications and 1 inversion,\n // instead of doing n inversions.\n divisorProd := 1\n\n for {\n let i := 0\n } lt(i, length) {\n i := add(i, 1)\n } {\n // tmp points to g^i\n // first 32 bytes of reference is the length of an array\n tmp := mload(add(add(localDomainElements, 0x20), mul(i, 0x20)))\n // compute (zeta - g^i)\n ithDivisor := addmod(sub(p, tmp), zeta, p)\n // accumulate (zeta - g^i) to the divisorProd\n divisorProd := mulmod(divisorProd, ithDivisor, p)\n // store ithDivisor in the array\n mstore(add(add(divisors, 0x20), mul(i, 0x20)), ithDivisor)\n }\n }\n\n // compute 1 / \\prod_{i=0}^length (zeta - g^i)\n divisorProd = BN254.invert(divisorProd);\n\n assembly {\n for {\n let i := 0\n } lt(i, length) {\n i := add(i, 1)\n } {\n // tmp points to g^i\n // first 32 bytes of reference is the length of an array\n tmp := mload(add(add(localDomainElements, 0x20), mul(i, 0x20)))\n // vanish_eval_div_n * g^i\n ithLagrange := mulmod(vanishEvalDivN, tmp, p)\n\n // now we compute vanish_eval_div_n * g^i / (zeta - g^i) via\n // vanish_eval_div_n * g^i * divisorProd * \\prod_{j!=i} (zeta - g^j)\n ithLagrange := mulmod(ithLagrange, divisorProd, p)\n for {\n let j := 0\n } lt(j, length) {\n j := add(j, 1)\n } {\n if iszero(eq(i, j)) {\n ithDivisor := mload(add(add(divisors, 0x20), mul(j, 0x20)))\n ithLagrange := mulmod(ithLagrange, ithDivisor, p)\n }\n }\n\n // multiply by pub_input[i] and update res\n // tmp points to public input\n tmp := mload(add(add(pi, 0x20), mul(i, 0x20)))\n ithLagrange := mulmod(ithLagrange, tmp, p)\n res := addmod(res, ithLagrange, p)\n }\n }\n }\n\n /// @dev Generate the domain elements for indexes 0..length\n /// which are essentially g^0, g^1, ..., g^{length-1}\n function domainElements(EvalDomain memory self, uint256 length)\n internal\n pure\n returns (uint256[] memory elements)\n {\n uint256 groupGen = self.groupGen;\n uint256 tmp = 1;\n uint256 p = BN254.R_MOD;\n elements = new uint256[](length);\n assembly {\n if not(iszero(length)) {\n let ptr := add(elements, 0x20)\n let end := add(ptr, mul(0x20, length))\n mstore(ptr, 1)\n ptr := add(ptr, 0x20)\n // for (; ptr < end; ptr += 32) loop through the memory of `elements`\n for {\n\n } lt(ptr, end) {\n ptr := add(ptr, 0x20)\n } {\n tmp := mulmod(tmp, groupGen, p)\n mstore(ptr, tmp)\n }\n }\n }\n }\n}\n" + }, + "contracts/mocks/TestPolynomialEval.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {PolynomialEval} from \"../libraries/PolynomialEval.sol\";\n\ncontract TestPolynomialEval {\n function evaluateVanishingPoly(PolynomialEval.EvalDomain memory self, uint256 zeta)\n public\n pure\n returns (uint256)\n {\n return PolynomialEval.evaluateVanishingPoly(self, zeta);\n }\n\n function evaluateLagrange(\n PolynomialEval.EvalDomain memory self,\n uint256 zeta,\n uint256 vanishEval\n ) public view returns (uint256) {\n return PolynomialEval.evaluateLagrangeOne(self, zeta, vanishEval);\n }\n\n function evaluatePiPoly(\n PolynomialEval.EvalDomain memory self,\n uint256[] memory pi,\n uint256 zeta,\n uint256 vanishEval\n ) public view returns (uint256) {\n return PolynomialEval.evaluatePiPoly(self, pi, zeta, vanishEval);\n }\n\n function newEvalDomain(uint256 domainSize)\n public\n pure\n returns (PolynomialEval.EvalDomain memory)\n {\n if (domainSize >= 32768) {\n return PolynomialEval.newEvalDomain(domainSize);\n } else if (domainSize == 32) {\n // support smaller domains for testing\n return\n PolynomialEval.EvalDomain(\n 5,\n domainSize,\n 0x2EE12BFF4A2813286A8DC388CD754D9A3EF2490635EBA50CB9C2E5E750800001,\n 0x09C532C6306B93D29678200D47C0B2A99C18D51B838EEB1D3EED4C533BB512D0,\n 0x2724713603BFBD790AEAF3E7DF25D8E7EF8F311334905B4D8C99980CF210979D\n );\n } else {\n revert(\"domain size not supported\");\n }\n }\n}\n" + }, + "contracts/mocks/TestPlonkVerifier.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {BN254} from \"../libraries/BN254.sol\";\nimport {PlonkVerifier as V} from \"../verifier/PlonkVerifier.sol\";\nimport {PolynomialEval as Poly} from \"../libraries/PolynomialEval.sol\";\nimport {TestPolynomialEval as TestPoly} from \"../mocks/TestPolynomialEval.sol\";\nimport \"hardhat/console.sol\";\n\ncontract TestPlonkVerifier is V, TestPoly {\n function computeLinPolyConstantTerm(\n Challenges memory chal,\n PlonkProof memory proof,\n Poly.EvalData memory evalData\n ) public pure returns (uint256 res) {\n return V._computeLinPolyConstantTerm(chal, proof, evalData);\n }\n\n function prepareEvaluations(\n uint256 linPolyConstant,\n PlonkProof memory proof,\n uint256[] memory scalars\n ) public pure returns (uint256 eval) {\n return V._prepareEvaluations(linPolyConstant, proof, scalars);\n }\n\n function batchVerifyOpeningProofs(PcsInfo[] memory pcsInfos) public view returns (bool) {\n return V._batchVerifyOpeningProofs(pcsInfos);\n }\n\n function computeChallenges(\n V.VerifyingKey memory verifyingKey,\n uint256[] memory publicInput,\n V.PlonkProof memory proof,\n bytes memory extraTranscriptInitMsg\n ) public pure returns (V.Challenges memory) {\n return V._computeChallenges(verifyingKey, publicInput, proof, extraTranscriptInitMsg);\n }\n\n function linearizationScalarsAndBases(\n V.VerifyingKey memory verifyingKey,\n V.Challenges memory challenge,\n Poly.EvalData memory evalData,\n V.PlonkProof memory proof\n ) public pure returns (BN254.G1Point[] memory bases, uint256[] memory scalars) {\n bases = new BN254.G1Point[](30);\n scalars = new uint256[](30);\n\n V._linearizationScalarsAndBases(verifyingKey, challenge, evalData, proof, bases, scalars);\n }\n\n function preparePolyCommitments(\n VerifyingKey memory verifyingKey,\n Challenges memory chal,\n Poly.EvalData memory evalData,\n PlonkProof memory proof\n ) public pure returns (uint256[] memory commScalars, BN254.G1Point[] memory commBases) {\n commBases = new BN254.G1Point[](30);\n commScalars = new uint256[](30);\n V._preparePolyCommitments(verifyingKey, chal, evalData, proof, commScalars, commBases);\n }\n\n // helper so that test code doesn't have to deploy both PlonkVerifier.sol and BN254.sol\n function multiScalarMul(BN254.G1Point[] memory bases, uint256[] memory scalars)\n public\n view\n returns (BN254.G1Point memory)\n {\n return BN254.multiScalarMul(bases, scalars);\n }\n\n function preparePcsInfo(\n VerifyingKey memory verifyingKey,\n uint256[] memory publicInput,\n PlonkProof memory proof,\n bytes memory extraTranscriptInitMsg\n ) public view returns (PcsInfo memory res) {\n require(publicInput.length == verifyingKey.numInputs, \"Plonk: wrong verifying key\");\n\n Challenges memory chal = V._computeChallenges(\n verifyingKey,\n publicInput,\n proof,\n extraTranscriptInitMsg\n );\n\n // NOTE: the only difference with actual code\n Poly.EvalDomain memory domain = newEvalDomain(verifyingKey.domainSize);\n // pre-compute evaluation data\n Poly.EvalData memory evalData = Poly.evalDataGen(domain, chal.zeta, publicInput);\n\n // compute opening proof in poly comm.\n uint256[] memory commScalars = new uint256[](30);\n BN254.G1Point[] memory commBases = new BN254.G1Point[](30);\n\n uint256 eval = _prepareOpeningProof(\n verifyingKey,\n evalData,\n proof,\n chal,\n commScalars,\n commBases\n );\n\n uint256 zeta = chal.zeta;\n uint256 omega = domain.groupGen;\n uint256 p = BN254.R_MOD;\n uint256 zetaOmega;\n assembly {\n zetaOmega := mulmod(zeta, omega, p)\n }\n\n res = PcsInfo(\n chal.u,\n zeta,\n zetaOmega,\n eval,\n commScalars,\n commBases,\n proof.zeta,\n proof.zetaOmega\n );\n }\n\n function testBatchVerify(\n VerifyingKey[] memory verifyingKeys,\n uint256[][] memory publicInputs,\n PlonkProof[] memory proofs,\n bytes[] memory extraTranscriptInitMsgs\n ) public view returns (bool) {\n require(\n verifyingKeys.length == proofs.length &&\n publicInputs.length == proofs.length &&\n extraTranscriptInitMsgs.length == proofs.length,\n \"Plonk: invalid input param\"\n );\n require(proofs.length > 0, \"Plonk: need at least 1 proof\");\n\n PcsInfo[] memory pcsInfos = new PcsInfo[](proofs.length);\n for (uint256 i = 0; i < proofs.length; i++) {\n // validate proofs are proper group/field elements\n V._validateProof(proofs[i]);\n\n // validate public input are all proper scalar fields\n for (uint256 j = 0; j < publicInputs[i].length; j++) {\n BN254.validateScalarField(publicInputs[i][j]);\n }\n\n // NOTE: only difference with actual code\n pcsInfos[i] = preparePcsInfo(\n verifyingKeys[i],\n publicInputs[i],\n proofs[i],\n extraTranscriptInitMsgs[i]\n );\n }\n\n return _batchVerifyOpeningProofs(pcsInfos);\n }\n}\n" + }, + "contracts/RescueNonOptimized.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"hardhat/console.sol\";\n\ncontract RescueNonOptimized {\n /// The constants are obtained from the Sage script\n /// https://github.com/EspressoSystems/Marvellous/blob/fcd4c41672f485ac2f62526bc87a16789d4d0459/rescue254.sage\n\n uint256 internal constant _N_ROUNDS = 12;\n uint256 internal constant _STATE_SIZE = 4;\n uint256 internal constant _SCHEDULED_KEY_SIZE = (2 * _N_ROUNDS + 1) * _STATE_SIZE;\n uint256 internal constant _MDS_SIZE = _STATE_SIZE * _STATE_SIZE;\n\n // Obtained by running KeyScheduling([0,0,0,0]). See Algorithm 2 of AT specification document.\n // solhint-disable-next-line var-name-mixedcase\n uint256[_SCHEDULED_KEY_SIZE] internal _SCHEDULED_KEY = [\n // Init key injection\n 14613516837064033601098425266946467918409544647446217386229959902054563533267,\n 376600575581954944138907282479272751264978206975465380433764825531344567663,\n 7549886658634274343394883631367643327196152481472281919735617268044202589860,\n 3682071510138521345600424597536598375718773365536872232193107639375194756918,\n // i = 0\n 18657517374128716281071590782771170166993445602755371021955596036781411817786,\n 7833794394096838639430144230563403530989402760602204539559270044687522640191,\n 21303828694647266539931030987057572024333442749881970102454081226349775826204,\n 10601447988834057856019990466870413629636256450824419416829818546423193802418,\n // i = 1\n 3394657260998945409283098835682964352503279447198495330506177586645995289229,\n 18437084083724939316390841967750487133622937044030373241106776324730657101302,\n 9281739916935170266925270432337475828741505406943764438550188362765269530037,\n 7363758719535652813463843693256839865026387361836644774317493432208443086206,\n // i = 2\n 307094088106440279963968943984309088038734274328527845883669678290790702381,\n 20802277384865839022876847241719852837518994021170013346790603773477912819001,\n 19754579269464973651593381036132218829220609572271224048608091445854164824042,\n 3618840933841571232310395486452077846249117988789467996234635426899783130819,\n // i = 3\n 2604166168648013711791424714498680546427073388134923208733633668316805639713,\n 21355705619901626246699129842094174300693414345856149669339147704587730744579,\n 492957643799044929042114590851019953669919577182050726596188173945730031352,\n 8495959434717951575638107349559891417392372124707619959558593515759091841138,\n // i = 4\n 15608173629791582453867933160400609222904457931922627396107815347244961625587,\n 16346164988481725869223011419855264063160651334419415042919928342589111681923,\n 21085652277104054699752179865196164165969290053517659864117475352262716334100,\n 20640310021063232205677193759981403045043444605175178332133134865746039279935,\n // i = 5\n 6015589261538006311719125697023069952804098656652050863009463360598997670240,\n 12498423882721726012743791752811798719201859023192663855805526312393108407357,\n 10785527781711732350693172404486938622378708235957779975342240483505724965040,\n 5563181134859229953817163002660048854420912281911747312557025480927280392569,\n // i = 6\n 4585980485870975597083581718044393941512074846925247225127276913719050121968,\n 8135760428078872176830812746579993820254685977237403304445687861806698035222,\n 4525715538433244696411192727226186804883202134636681498489663161593606654720,\n 2537497100749435007113677475828631400227339157221711397900070636998427379023,\n // i = 7\n 6957758175844522415482704083077249782181516476067074624906502033584870962925,\n 17134288156316028142861248367413235848595762718317063354217292516610545487813,\n 20912428573104312239411321877435657586184425249645076131891636094671938892815,\n 16000236205755938926858829908701623009580043315308207671921283074116709575629,\n // i = 8\n 10226182617544046880850643054874064693998595520540061157646952229134207239372,\n 18584346134948015676264599354709457865255277240606855245909703396343731224626,\n 9263628039314899758000383385773954136696958567872461042004915206775147151562,\n 21095966719856094705113273596585696209808876361583941931684481364905087347856,\n // i = 9\n 2671157351815122058649197205531097090514563992249109660044882868649840700911,\n 19371695134219415702961622134896564229962454573253508904477489696588594622079,\n 5458968308231210904289987830881528056037123818964633914555287871152343390175,\n 7336332584551233792026746889434554547883125466404119632794862500961953384162,\n // i = 10\n 10351436748086126474964482623536554036637945319698748519226181145454116702488,\n 10588209357420186457766745724579739104572139534486480334142455690083813419064,\n 14330277147584936710957102218096795520430543834717433464500965846826655802131,\n 20752197679372238381408962682213349118865256502118746003818603260257076802028,\n // i = 11\n 19390446529582160674621825412345750405397926216690583196542690617266028463414,\n 4169994013656329171830126793466321040216273832271989491631696813297571003664,\n 3014817248268674641565961681956715664833306954478820029563459099892548946802,\n 14285412497877984113655094566695921704826935980354186365694472961163628072901,\n // i = 12\n 16224484149774307577146165975762490690838415946665379067259822320752729067513,\n 5404416528124718330316441408560295270695591369912905197499507811036327404407,\n 20127204244332635127213425090893250761286848618448128307344971109698523903374,\n 14939477686176063572999014162186372798386193194442661892600584389296609365740,\n // i = 13\n 183740587182448242823071506013879595265109215202349952517434740768878294134,\n 15366166801397358994305040367078329374182896694582870542425225835844885654667,\n 10066796014802701613007252979619633540090232697942390802486559078446300507813,\n 4824035239925904398047276123907644574421550988870123756876333092498925242854,\n // i = 14\n 5526416022516734657935645023952329824887761902324086126076396040056459740202,\n 18157816292703983306114736850721419851645159304249709756659476015594698876611,\n 767446206481623130855439732549764381286210118638028499466788453347759203223,\n 16303412231051555792435190427637047658258796056382698277687500021321460387129,\n // i = 15\n 15475465085113677237835653765189267963435264152924949727326000496982746660612,\n 14574823710073720047190393602502575509282844662732045439760066078137662816054,\n 13746490178929963947720756220409862158443939172096620003896874772477437733602,\n 13804898145881881347835367366352189037341704254740510664318597456840481739975,\n // i = 16\n 3523599105403569319090449327691358425990456728660349400211678603795116364226,\n 8632053982708637954870974502506145434219829622278773822242070316888003350278,\n 20293222318844554840191640739970825558851264905959070636369796127300969629060,\n 7583204376683983181255811699503668584283525661852773339144064901897953897564,\n // i = 17\n 7562572155566079175343789986900217168516831778275127159068657756836798778249,\n 12689811910161401007144285031988539999455902164332232460061366402869461973371,\n 21878400680687418538050108788381481970431106443696421074205107984690362920637,\n 3428721187625124675258692786364137915132424621324969246210899039774126165479,\n // i = 18\n 2552744099402346352193097862110515290335034445517764751557635302899937367219,\n 13706727374402840004346872704605212996406886221231239230397976011930486183550,\n 19786308443934570499119114884492461847023732197118902978413499381102456961966,\n 11767081169862697956461405434786280425108140215784390008330611807075539962898,\n // i = 19\n 1273319740931699377003430019539548781935202579355152343831464213279794249000,\n 20225620070386241931202098463018472034137960205721651875253423327929063224115,\n 13107884970924459680133954992354588464904218518440707039430314610799573960437,\n 10574066469653966216567896842413898230152427846140046825523989742590727910280,\n // i = 20\n 21386271527766270535632132320974945129946865648321206442664310421414128279311,\n 15743262855527118149527268525857865250723531109306484598629175225221686341453,\n 16251140915157602891864152518526119259367827194524273940185283798897653655734,\n 5420158299017134702074915284768041702367316125403978919545323705661634647751,\n // i = 21\n 14555572526833606349832007897859411042036463045080050783981107823326880950231,\n 15234942318869557310939446038663331226792664588406507247341043508129993934298,\n 19560004467494472556570844694553210033340577742756929194362924850760034377042,\n 21851693551359717578445799046408060941161959589978077352548456186528047792150,\n // i = 22\n 19076469206110044175016166349949136119962165667268661130584159239385341119621,\n 19132104531774396501521959463346904008488403861940301898725725957519076019017,\n 6606159937109409334959297158878571243749055026127553188405933692223704734040,\n 13442678592538344046772867528443594004918096722084104155946229264098946917042,\n // i = 23\n 11975757366382164299373991853632416786161357061467425182041988114491638264212,\n 10571372363668414752587603575617060708758897046929321941050113299303675014148,\n 5405426474713644587066466463343175633538103521677501186003868914920014287031,\n 18665277628144856329335676361545218245401014824195451740181902217370165017984\n ];\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[_MDS_SIZE] internal _MDS = [\n 21888242871839275222246405745257275088548364400416034343698204186575808479992,\n 21888242871839275222246405745257275088548364400416034343698204186575806058117,\n 21888242871839275222246405745257275088548364400416034343698204186575491214367,\n 21888242871839275222246405745257275088548364400416034343698204186535831058117,\n 19500,\n 3026375,\n 393529500,\n 49574560750,\n 21888242871839275222246405745257275088548364400416034343698204186575808491587,\n 21888242871839275222246405745257275088548364400416034343698204186575807886437,\n 21888242871839275222246405745257275088548364400416034343698204186575729688812,\n 21888242871839275222246405745257275088548364400416034343698204186565891044437,\n 156,\n 20306,\n 2558556,\n 320327931\n ];\n\n uint256 internal constant _PRIME =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n uint256 internal constant _ALPHA = 5;\n\n uint256 internal constant _ALPHA_INV =\n 17510594297471420177797124596205820070838691520332827474958563349260646796493;\n\n function expMod(\n uint256 base,\n uint256 e,\n uint256 m\n ) public view returns (uint256 o) {\n assembly {\n // define pointer\n let p := mload(0x40)\n // store data assembly-favouring ways\n mstore(p, 0x20) // Length of Base\n mstore(add(p, 0x20), 0x20) // Length of Exponent\n mstore(add(p, 0x40), 0x20) // Length of Modulus\n mstore(add(p, 0x60), base) // Base\n mstore(add(p, 0x80), e) // Exponent\n mstore(add(p, 0xa0), m) // Modulus\n if iszero(staticcall(sub(gas(), 2000), 0x05, p, 0xc0, p, 0x20)) {\n revert(0, 0)\n }\n // data\n o := mload(p)\n }\n }\n\n function _addVectors(uint256[_STATE_SIZE] memory v1, uint256[_STATE_SIZE] memory v2)\n internal\n pure\n returns (uint256[_STATE_SIZE] memory)\n {\n uint256[_STATE_SIZE] memory v;\n\n for (uint256 j = 0; j < _STATE_SIZE; j++) {\n v[j] = addmod(v1[j], v2[j], _PRIME);\n }\n\n return v;\n }\n\n // _MDS is hardcoded\n function _linearOp(uint256[_STATE_SIZE] memory state, uint256[_STATE_SIZE] memory key)\n private\n view\n returns (uint256[_STATE_SIZE] memory)\n {\n uint256[_STATE_SIZE] memory newState = [uint256(0), 0, 0, 0];\n\n // Matrix multiplication\n for (uint256 i = 0; i < _STATE_SIZE; i++) {\n uint256 sum = uint256(0);\n for (uint256 j = 0; j < _STATE_SIZE; j++) {\n sum = addmod(sum, mulmod(_MDS[i * _STATE_SIZE + j], state[j], _PRIME), _PRIME);\n }\n newState[i] = sum;\n }\n\n // Add constant\n newState = _addVectors(newState, key);\n\n return newState;\n }\n\n // Computes the Rescue permutation on some input\n // Recall that the scheduled key is precomputed in our case\n // @param input input for the permutation\n // @return permutation output\n function _perm(uint256[_STATE_SIZE] memory input)\n internal\n view\n returns (uint256[_STATE_SIZE] memory)\n {\n uint256[_STATE_SIZE] memory key0 = [\n _SCHEDULED_KEY[0],\n _SCHEDULED_KEY[1],\n _SCHEDULED_KEY[2],\n _SCHEDULED_KEY[3]\n ];\n\n // S = m + k[0]\n uint256[_STATE_SIZE] memory S = _addVectors(input, key0); // solhint-disable-line var-name-mixedcase\n\n // Main loop\n for (uint256 i = 1; i < 2 * _N_ROUNDS + 1; i++) {\n if ((i - 1) % 2 == 0) {\n S[0] = expMod(S[0], _ALPHA_INV, _PRIME);\n S[1] = expMod(S[1], _ALPHA_INV, _PRIME);\n S[2] = expMod(S[2], _ALPHA_INV, _PRIME);\n S[3] = expMod(S[3], _ALPHA_INV, _PRIME);\n } else {\n S[0] = expMod(S[0], _ALPHA, _PRIME);\n S[1] = expMod(S[1], _ALPHA, _PRIME);\n S[2] = expMod(S[2], _ALPHA, _PRIME);\n S[3] = expMod(S[3], _ALPHA, _PRIME);\n }\n\n uint256[_STATE_SIZE] memory keyI = [\n _SCHEDULED_KEY[i * _STATE_SIZE],\n _SCHEDULED_KEY[i * _STATE_SIZE + 1],\n _SCHEDULED_KEY[i * _STATE_SIZE + 2],\n _SCHEDULED_KEY[i * _STATE_SIZE + 3]\n ];\n S = _linearOp(S, keyI);\n }\n return S;\n }\n\n // Computes the hash of three field elements and returns a single element\n // In our case the rate is 3 and the capacity is 1\n // This hash function the one used in the Records Merkle tree.\n // @param a first element\n // @param b second element\n // @param c third element\n // @return the first element of the Rescue state\n function hash(\n uint256 a,\n uint256 b,\n uint256 c\n ) public view returns (uint256) {\n uint256[_STATE_SIZE] memory input;\n uint256[_STATE_SIZE] memory state;\n\n input[0] = a;\n input[1] = b;\n input[2] = c;\n input[3] = 0;\n\n state = _perm(input);\n\n return state[0];\n }\n\n function commit(uint256[15] memory inputs) public view returns (uint256) {\n uint256 a = inputs[0];\n uint256 b = inputs[1];\n uint256 c = inputs[2];\n uint256 d;\n require(a < _PRIME, \"inputs must be below _PRIME\");\n require(b < _PRIME, \"inputs must be below _PRIME\");\n require(c < _PRIME, \"inputs must be below _PRIME\");\n\n for (uint256 i = 0; i < 5; i++) {\n require(inputs[3 * i + 0] < _PRIME, \"inputs must be below _PRIME\");\n require(inputs[3 * i + 1] < _PRIME, \"inputs must be below _PRIME\");\n require(inputs[3 * i + 2] < _PRIME, \"inputs must be below _PRIME\");\n a += inputs[3 * i + 0];\n b += inputs[3 * i + 1];\n c += inputs[3 * i + 2];\n uint256[4] memory state = [a % _PRIME, b % _PRIME, c % _PRIME, d % _PRIME];\n state = _perm(state);\n (a, b, c, d) = (state[0], state[1], state[2], state[3]);\n }\n\n return a % _PRIME;\n }\n}\n" + }, + "contracts/mocks/TestRescueNonOptimized.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"hardhat/console.sol\";\nimport \"../RescueNonOptimized.sol\";\n\ncontract TestRescueNonOptimized is RescueNonOptimized {\n function doNothing() public {}\n}\n" + }, + "contracts/mocks/TestRescue.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"hardhat/console.sol\";\nimport \"../libraries/RescueLib.sol\";\n\ncontract TestRescue {\n function doNothing() public {}\n\n function hash(\n uint256 a,\n uint256 b,\n uint256 c\n ) public view returns (uint256) {\n return RescueLib.hash(a, b, c);\n }\n\n function commit(uint256[15] memory inputs) public view returns (uint256) {\n return RescueLib.commit(inputs);\n }\n}\n" + }, + "contracts/RecordsMerkleTree.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./libraries/RescueLib.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract RecordsMerkleTree is Ownable {\n enum Position {\n LEFT,\n MIDDLE,\n RIGHT\n }\n\n // Representation of a (tree) node\n // A node contains a value and pointers (which are index in an array of other nodes).\n // By convention a node that has no (left,middle,right) children will point to index 0.\n struct Node {\n uint256 val;\n uint64 left; // Pointer (index) to the left child\n uint64 middle; // Pointer (index) to the middle child\n uint64 right; // Pointer (index) to the right child\n }\n\n uint256 internal _rootValue;\n uint64 internal _numLeaves;\n uint8 internal _merkleTreeHeight;\n\n mapping(uint256 => uint256) internal _flattenedFrontier;\n\n /// @dev Create a records Merkle tree of the given height.\n /// @param merkleTreeHeight The height\n constructor(uint8 merkleTreeHeight) {\n _rootValue = 0;\n _numLeaves = 0;\n _merkleTreeHeight = merkleTreeHeight;\n }\n\n /// @dev Is the given node a terminal node?\n /// @param node A node\n /// @return _ True if the node is terminal, false otherwise.\n function _isTerminal(Node memory node) private pure returns (bool) {\n return (node.left == 0) && (node.middle == 0) && (node.right == 0);\n }\n\n /// @dev Is the given node null?\n /// @param node A node\n /// @return _ True if the node is NULL, false otherwise\n function _isNull(Node memory node) private pure returns (bool) {\n return (node.val == 0 && _isTerminal(node));\n }\n\n /// @dev Create a new \"hole node\" at the given position in the\n /// tree. A cursor position can be obtained from an extant node or\n /// from a function that returns a position such as _buildTreeFromFrontier.\n /// @param cursor The index of the node in the array of nodes\n /// @param posSibling The position of the sibling i.e. (LEFT, MIDDLE or RIGHT)\n /// @return _ The new created node\n function _createHoleNode(uint64 cursor, Position posSibling)\n private\n pure\n returns (Node memory)\n {\n // Copy pasting these values to save gas\n // indexHoleNode = cursor - 3;\n // indexFirstSibling = cursor - 2;\n // indexSecondSibling = cursor - 1;\n\n if (posSibling == Position.LEFT) {\n return Node(0, cursor - 3, cursor - 2, cursor - 1);\n } else if (posSibling == Position.MIDDLE) {\n return Node(0, cursor - 2, cursor - 3, cursor - 1);\n } else if (posSibling == Position.RIGHT) {\n return Node(0, cursor - 2, cursor - 1, cursor - 3);\n } else {\n revert(\"unreachable\");\n }\n }\n\n /// @dev Create a Merkle tree from the given frontier.\n /// @param nodes The list of nodes to be filled or updated\n /// @return A cursor to the root node of the create tree\n function _buildTreeFromFrontier(Node[] memory nodes) internal view returns (uint64) {\n // Tree is empty\n if (_numLeaves == 0) {\n nodes[0] = Node(0, 0, 0, 0); // Empty node\n nodes[1] = Node(0, 0, 0, 0); // Root node\n return 1;\n }\n\n // Tree is not empty\n\n // Set the first node to the NULL node\n nodes[0] = Node(0, 0, 0, 0);\n\n // Insert the leaf\n nodes[1] = Node(_flattenedFrontier[0], 0, 0, 0);\n\n // Insert the siblings\n nodes[2] = Node(_flattenedFrontier[1], 0, 0, 0);\n nodes[3] = Node(_flattenedFrontier[2], 0, 0, 0);\n\n // Compute the position of each node\n uint64 absolutePosition = _numLeaves - 1;\n uint8 localPosition = uint8(absolutePosition % 3);\n\n // We process the nodes of the Merkle path\n uint64 cursor = 4;\n uint64 cursorFrontier = 3;\n\n // Build the tree expect the root node\n while (cursor < 3 * _merkleTreeHeight + 1) {\n nodes[cursor] = _createHoleNode(cursor, Position(localPosition));\n\n // Create the siblings of the \"hole node\". These siblings have no children\n nodes[cursor + 1] = Node(_flattenedFrontier[cursorFrontier], 0, 0, 0);\n nodes[cursor + 2] = Node(_flattenedFrontier[cursorFrontier + 1], 0, 0, 0);\n\n // Move forward\n absolutePosition /= 3;\n localPosition = uint8(absolutePosition % 3);\n\n cursor += 3;\n cursorFrontier += 2;\n }\n\n // Add the root node\n nodes[cursor] = _createHoleNode(cursor, Position(localPosition));\n return cursor;\n }\n\n /// @dev Compute the index of the next node when going down in the tree.\n /// @param nodes The list of nodes of the tree\n /// @param nodeIndex The index of the starting node\n /// @param pos The position for going down, i.e. LEFT, MIDDLE or RIGHT.\n /// @return The index of the next node\n function _nextNodeIndex(\n Node[] memory nodes,\n uint64 nodeIndex,\n Position pos\n ) private pure returns (uint64) {\n if (pos == Position.LEFT) {\n return nodes[nodeIndex].left;\n } else if (pos == Position.MIDDLE) {\n return nodes[nodeIndex].middle;\n } else if (pos == Position.RIGHT) {\n return nodes[nodeIndex].right;\n } else {\n revert(\"unreachable\");\n }\n }\n\n /// @dev Update the child of a node based on the position (which child to select) and an index to the new child.\n /// @param node node for which we want to update the child\n /// @param newChildIndex index of the new child\n /// @param pos position of the child node relative to the node (i.e. LEFT, MIDDLE or RIGHT)\n function _updateChildNode(\n Node memory node,\n uint64 newChildIndex,\n Position pos\n ) private pure {\n // Update the node\n if (pos == Position.LEFT) {\n node.left = newChildIndex;\n } else if (pos == Position.MIDDLE) {\n node.middle = newChildIndex;\n } else if (pos == Position.RIGHT) {\n node.right = newChildIndex;\n }\n }\n\n function _computeNodePos(uint64 absolutePos, uint64 branchIndex)\n private\n view\n returns (uint64, uint64)\n {\n uint64 localPos;\n uint64 divisor = uint64(3**(_merkleTreeHeight - branchIndex - 1));\n\n localPos = absolutePos / divisor;\n absolutePos = absolutePos % divisor;\n\n return (absolutePos, localPos);\n }\n\n /// @notice Insert an element into the tree in the position num_leaves.\n /// @param nodes The array of nodes\n /// @param rootIndex The index of the root node\n /// @param maxIndex The index of the latest element inserted in the nodes array\n /// @param element The value of the element to insert into the tree\n /// @return updated the value of maxIndex\n function _pushElement(\n Node[] memory nodes,\n uint64 rootIndex,\n uint64 maxIndex,\n uint256 element\n ) private returns (uint64) {\n require(_numLeaves < 3**_merkleTreeHeight, \"The tree is full.\");\n\n // Get the position of the leaf from the smart contract state\n uint64 leafPos = _numLeaves;\n uint64 branchIndex = 0;\n uint64 currentNodeIndex = rootIndex;\n uint64 previousNodeIndex = rootIndex;\n\n // Go down inside the tree until finding the first terminal node.\n uint64 absolutePos = leafPos;\n uint64 localPos = 0;\n while (!_isNull(nodes[currentNodeIndex])) {\n (absolutePos, localPos) = _computeNodePos(absolutePos, branchIndex);\n\n previousNodeIndex = currentNodeIndex;\n currentNodeIndex = _nextNodeIndex(nodes, currentNodeIndex, Position(localPos));\n\n branchIndex += 1;\n }\n\n // maxIndex tracks the index of the last element inserted in the tree\n uint64 newNodeIndex = maxIndex + 1;\n\n // Create new nodes until completing the path one level above the leaf level\n // Always inserting to the left\n\n // To compensate the extra increment at the end of the previous loop ,\n // except if the tree is reduced to a single root node.\n if (branchIndex > 0) {\n branchIndex -= 1;\n }\n\n while (branchIndex < _merkleTreeHeight - 1) {\n nodes[newNodeIndex] = Node(0, 0, 0, 0);\n _updateChildNode(nodes[previousNodeIndex], newNodeIndex, Position(localPos));\n\n // Prepare the next iteration of the loop\n previousNodeIndex = newNodeIndex;\n newNodeIndex += 1;\n branchIndex += 1;\n (absolutePos, localPos) = _computeNodePos(absolutePos, branchIndex);\n }\n\n // The last node contains the leaf value (compute the hash)\n // Remember position is computed with the remainder\n\n // Leaf node where the value is hash(0,_numLeaves,element)\n uint256 val = RescueLib.hash(0, _numLeaves, element);\n nodes[newNodeIndex] = Node(val, 0, 0, 0);\n _updateChildNode(nodes[previousNodeIndex], newNodeIndex, Position(localPos));\n\n // Increment the number of leaves\n //\n // This operation is costly and happens in a loop. However, for now the\n // merkle tree is usually updated with a single new element. In this\n // case we would not save gas by moving the update of _numLeaves. The\n // gas cost is also likely negligible compared to the whole operation of\n // inserting an element.\n //\n // slither-disable-next-line costly-loop\n _numLeaves += 1;\n\n // Return the new value of maxIndex\n return newNodeIndex;\n }\n\n /// @dev Store the frontier.\n /// @param nodes The list of node of the tree\n /// @param rootIndex The index of the root node\n function _storeFrontier(Node[] memory nodes, uint64 rootIndex) private {\n uint64 frontierSize = 2 * _merkleTreeHeight + 1;\n\n /// Collect the values from the root to the leaf but in reverse order\n uint64 currentNodeIndex = rootIndex;\n uint64 firstSiblingIndex = 0;\n uint64 secondSiblingIndex = 0;\n // Go down until the leaf\n for (uint256 i = 0; i < _merkleTreeHeight; i++) {\n // Pick the non-empty node that is most right\n Node memory currentNode = nodes[currentNodeIndex];\n if (!_isNull(nodes[currentNode.right])) {\n // Keep to the right\n currentNodeIndex = currentNode.right;\n firstSiblingIndex = currentNode.left;\n secondSiblingIndex = currentNode.middle;\n } else if (!_isNull(nodes[currentNode.middle])) {\n // Keep to the middle\n currentNodeIndex = currentNode.middle;\n firstSiblingIndex = currentNode.left;\n secondSiblingIndex = currentNode.right;\n } else {\n // Keep to the left\n currentNodeIndex = currentNode.left;\n firstSiblingIndex = currentNode.middle;\n secondSiblingIndex = currentNode.right;\n }\n uint256 secondSiblingPos = frontierSize - 1 - (2 * i);\n uint256 firstSiblingPos = secondSiblingPos - 1;\n _flattenedFrontier[secondSiblingPos] = nodes[secondSiblingIndex].val;\n _flattenedFrontier[firstSiblingPos] = nodes[firstSiblingIndex].val;\n }\n // currentNodeIndex points to the leaf\n _flattenedFrontier[0] = nodes[currentNodeIndex].val;\n }\n\n /// @dev Update the state of the record merkle tree by inserting new elements.\n /// @param elements The list of elements to be appended to the current merkle tree described by the frontier.\n function updateRecordsMerkleTree(uint256[] memory elements) external onlyOwner {\n // The total number of nodes is bounded by 3*height+1 + 3*N*height = 3*(N+1)*height + 1\n // where N is the number of new records\n uint256 numElements = elements.length;\n Node[] memory nodes = new Node[](3 * (numElements + 1) * _merkleTreeHeight + 2);\n\n /// Insert the new elements ///\n\n // maxIndex tracks the index of the last element inserted in the tree\n uint64 rootIndex = _buildTreeFromFrontier(nodes);\n uint64 maxIndex = rootIndex;\n for (uint32 i = 0; i < elements.length; i++) {\n maxIndex = _pushElement(nodes, rootIndex, maxIndex, elements[i]);\n }\n //// Compute the root hash value ////\n _rootValue = _computeRootValueAndUpdateTree(nodes, rootIndex);\n\n //// Store the frontier\n _storeFrontier(nodes, rootIndex);\n }\n\n /// @notice Returns the root value of the Merkle tree.\n function getRootValue() external view returns (uint256) {\n return _rootValue;\n }\n\n /// @notice Returns the height of the Merkle tree.\n function getHeight() external view returns (uint8) {\n return _merkleTreeHeight;\n }\n\n /// @notice Returns the number of leaves of the Merkle tree.\n function getNumLeaves() external view returns (uint64) {\n return _numLeaves;\n }\n\n /// @dev Update the tree by hashing the children of each node.\n /// @param nodes The tree. Note that the nodes are updated by this function.\n /// @param rootNodePos The index of the root node in the list of nodes.\n /// @return The value obtained at the root.\n function _computeRootValueAndUpdateTree(Node[] memory nodes, uint256 rootNodePos)\n private\n returns (uint256)\n {\n // If the root node has no children return its value\n Node memory rootNode = nodes[rootNodePos];\n if (_isTerminal(rootNode)) {\n return rootNode.val;\n } else {\n uint256 valLeft = _computeRootValueAndUpdateTree(nodes, rootNode.left);\n uint256 valMiddle = _computeRootValueAndUpdateTree(nodes, rootNode.middle);\n uint256 valRight = _computeRootValueAndUpdateTree(nodes, rootNode.right);\n\n nodes[rootNode.left].val = valLeft;\n nodes[rootNode.middle].val = valMiddle;\n nodes[rootNode.right].val = valRight;\n\n return RescueLib.hash(valLeft, valMiddle, valRight);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _setOwner(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _setOwner(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _setOwner(newOwner);\n }\n\n function _setOwner(address newOwner) private {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\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" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/MaliciousToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {TestCAPE} from \"./mocks/TestCAPE.sol\";\n\n// Learn more about the ERC20 implementation\n// on OpenZeppelin docs: https://docs.openzeppelin.com/contracts/4.x/erc20\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MaliciousToken is ERC20 {\n address private _targetContractAddress;\n bool private _runDeposit;\n bool private _runSubmitBlock;\n\n /// @notice MaliciousToken contract constructor.\n constructor() ERC20(\"Malicious Token\", \"MAT\") {\n _runDeposit = false;\n _runSubmitBlock = false;\n }\n\n /**\n * /// @dev Sets the address for performing the reentrancy attack.\n */\n function setTargetContractAddress(address targetContractAddress) public {\n _targetContractAddress = targetContractAddress;\n }\n\n /**\n * /// @dev pick the depositErc20 function when calling back the CAPE contract\n */\n function selectDepositAttack() public {\n _runDeposit = true;\n _runSubmitBlock = false;\n }\n\n /**\n * /// @dev pick the submitBlock function when calling back the CAPE contract\n */\n function selectSubmitBlockAttack() public {\n _runDeposit = false;\n _runSubmitBlock = true;\n }\n\n /**\n * /// @notice Malicious implementation of transferFrom\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n TestCAPE cape = TestCAPE(_targetContractAddress);\n\n if (_runDeposit) {\n TestCAPE.RecordOpening memory dummyRo;\n address dummyAddress;\n cape.depositErc20(dummyRo, dummyAddress);\n }\n\n if (_runSubmitBlock) {\n TestCAPE.CapeBlock memory dummyBlock;\n cape.submitCapeBlock(dummyBlock);\n }\n\n return true;\n }\n}\n" + }, + "contracts/mocks/TestCAPE.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../CAPE.sol\";\n\ncontract TestCAPE is CAPE {\n constructor(\n uint64 nRoots,\n address verifierAddr,\n address recordsMerkleTreeAddr\n ) CAPE(nRoots, verifierAddr, recordsMerkleTreeAddr) {}\n\n function getNumLeaves() public view returns (uint256) {\n return _recordsMerkleTree.getNumLeaves();\n }\n\n function setInitialRecordCommitments(uint256[] memory elements) public {\n require(_recordsMerkleTree.getRootValue() == 0, \"Merkle tree is nonempty\");\n _recordsMerkleTree.updateRecordsMerkleTree(elements);\n addRoot(_recordsMerkleTree.getRootValue());\n }\n\n function publish(uint256 nullifier) public {\n return _publish(nullifier);\n }\n\n function checkTransfer(TransferNote memory note) public pure {\n return _checkTransfer(note);\n }\n\n function checkBurn(BurnNote memory note) public view {\n return _checkBurn(note);\n }\n\n function containsRoot(uint256 root) public view returns (bool) {\n return _containsRoot(root);\n }\n\n function containsBurnPrefix(bytes memory extraProofBoundData) public pure returns (bool) {\n return _containsBurnPrefix(extraProofBoundData);\n }\n\n function containsBurnRecord(BurnNote memory note) public view returns (bool) {\n return _containsBurnRecord(note);\n }\n\n function deriveRecordCommitment(RecordOpening memory ro) public view returns (uint256) {\n return _deriveRecordCommitment(ro);\n }\n\n function addRoot(uint256 root) public {\n return _addRoot(root);\n }\n\n function setHeight(uint64 newHeight) public {\n blockHeight = newHeight;\n }\n\n function computeNumCommitments(CapeBlock memory newBlock) public pure returns (uint256) {\n return _computeNumCommitments(newBlock);\n }\n\n function checkForeignAssetCode(\n uint256 assetDefinitionCode,\n address erc20Address,\n address sponsor,\n AssetPolicy memory policy\n ) public pure {\n _checkForeignAssetCode(assetDefinitionCode, erc20Address, sponsor, policy);\n }\n\n function checkDomesticAssetCode(uint256 assetDefinitionCode, uint256 internalAssetCode)\n public\n pure\n {\n _checkDomesticAssetCode(assetDefinitionCode, internalAssetCode);\n }\n\n function computeAssetDescription(\n address erc20Address,\n address sponsor,\n AssetPolicy memory policy\n ) public pure returns (bytes memory) {\n return _computeAssetDescription(erc20Address, sponsor, policy);\n }\n\n function pendingDepositsLength() public view returns (uint256) {\n return pendingDeposits.length;\n }\n\n function fillUpPendingDepositsQueue() public {\n for (uint256 i = pendingDeposits.length; i < MAX_NUM_PENDING_DEPOSIT; i++) {\n pendingDeposits.push(100 + i);\n }\n }\n}\n" + }, + "contracts/WrapToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\n// Learn more about the ERC20 implementation\n// on OpenZeppelin docs: https://docs.openzeppelin.com/contracts/4.x/erc20\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice This token is only intended to be used for testing.\ncontract WrapToken is ERC20 {\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {}\n\n /// @notice Allows minting tokens by sending Ether to it.\n receive() external payable {\n uint256 amount = msg.value / 10**(18 - decimals());\n _mint(msg.sender, amount);\n }\n\n function withdraw() external {\n uint256 balance = balanceOf(msg.sender);\n address payable sender = payable(msg.sender);\n _burn(sender, balance);\n sender.transfer(balance * 10**(18 - decimals()));\n }\n}\n" + }, + "contracts/WethToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./WrapToken.sol\";\n\ncontract WETH is WrapToken {\n constructor() WrapToken(\"Wrapped Ether\", \"WETH\") {}\n}\n" + }, + "contracts/USDC.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./WrapToken.sol\";\n\ncontract USDC is WrapToken {\n constructor() WrapToken(\"USD Coin\", \"USDC\") {}\n\n function decimals() public pure override returns (uint8) {\n return 6;\n }\n}\n" + }, + "contracts/SimpleToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./WrapToken.sol\";\n\ncontract SimpleToken is WrapToken {\n /// @notice The deployer receives 1e9 units.\n constructor() WrapToken(\"Simple Token\", \"SIT\") {\n _mint(msg.sender, 1_000_000_000);\n }\n}\n" + }, + "contracts/DaiToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"./WrapToken.sol\";\n\ncontract DAI is WrapToken {\n constructor() WrapToken(\"DAI Token\", \"DAI\") {}\n}\n" + }, + "contracts/mocks/TestRecordsMerkleTree.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"hardhat/console.sol\";\nimport {RecordsMerkleTree as R} from \"../RecordsMerkleTree.sol\";\nimport \"../libraries/RescueLib.sol\";\n\n// This contract is only used in a javascript benchmark and\n// could be removed.\ncontract TestRecordsMerkleTree is R {\n constructor(uint8 height) R(height) {}\n\n function doNothing() public {}\n}\n" + }, + "contracts/mocks/TestBN254.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {BN254 as C} from \"../libraries/BN254.sol\";\n\ncontract TestBN254 {\n constructor() {}\n\n // solhint-disable-next-line func-name-mixedcase\n function P1() public pure returns (C.G1Point memory) {\n return C.P1();\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function P2() public pure returns (C.G2Point memory) {\n return C.P2();\n }\n\n function isInfinity(C.G1Point memory point) public pure returns (bool) {\n return C.isInfinity(point);\n }\n\n function negateG1(C.G1Point memory p) public pure returns (C.G1Point memory r) {\n return C.negate(p);\n }\n\n function negateFr(uint256 fr) public pure returns (uint256 res) {\n return C.negate(fr);\n }\n\n function add(C.G1Point memory p1, C.G1Point memory p2) public view returns (C.G1Point memory) {\n return C.add(p1, p2);\n }\n\n function scalarMul(C.G1Point memory p, uint256 s) public view returns (C.G1Point memory r) {\n return C.scalarMul(p, s);\n }\n\n function invert(uint256 fr) public view returns (uint256 output) {\n return C.invert(fr);\n }\n\n function validateG1Point(C.G1Point memory point) public pure {\n C.validateG1Point(point);\n }\n\n function validateScalarField(uint256 fr) public pure {\n C.validateScalarField(fr);\n }\n\n function pairingProd2(\n C.G1Point memory a1,\n C.G2Point memory a2,\n C.G1Point memory b1,\n C.G2Point memory b2\n ) public view returns (bool) {\n return C.pairingProd2(a1, a2, b1, b2);\n }\n\n function fromLeBytesModOrder(bytes memory leBytes) public pure returns (uint256) {\n return C.fromLeBytesModOrder(leBytes);\n }\n\n function isYNegative(C.G1Point memory p) public pure returns (bool) {\n return C.isYNegative(p);\n }\n\n function powSmall(\n uint256 base,\n uint256 exponent,\n uint256 modulus\n ) public pure returns (uint256) {\n return C.powSmall(base, exponent, modulus);\n }\n\n function testMultiScalarMul(C.G1Point[] memory bases, uint256[] memory scalars)\n public\n view\n returns (C.G1Point memory)\n {\n return C.multiScalarMul(bases, scalars);\n }\n\n function g1Serialize(C.G1Point memory point) public pure returns (bytes memory res) {\n return C.g1Serialize(point);\n }\n\n function g1Deserialize(bytes32 input) public view returns (C.G1Point memory point) {\n return C.g1Deserialize(input);\n }\n\n function quadraticResidue(uint256 x) public view returns (bool isQuadraticResidue, uint256 a) {\n return C.quadraticResidue(x);\n }\n}\n" + }, + "contracts/mocks/TestRootStore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport \"../RootStore.sol\";\n\ncontract TestRootStore is RootStore {\n constructor(uint64 nRoots) RootStore(nRoots) {}\n\n function addRoot(uint256 lastRoot) public {\n _addRoot(lastRoot);\n }\n\n function containsRoot(uint256 root) public view returns (bool) {\n return _containsRoot(root);\n }\n\n function checkContainsRoot(uint256 root) public view {\n _checkContainsRoot(root);\n }\n}\n" + }, + "contracts/mocks/TestAccumulatingArray.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n//\n// Copyright (c) 2022 Espresso Systems (espressosys.com)\n// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library.\n//\n// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n// You should have received a copy of the GNU General Public License along with this program. If not, see .\n\npragma solidity ^0.8.0;\n\nimport {AccumulatingArray} from \"../libraries/AccumulatingArray.sol\";\n\ncontract TestAccumulatingArray {\n using AccumulatingArray for AccumulatingArray.Data;\n\n function accumulate(uint256[][] memory arrays, uint256 length)\n public\n pure\n returns (uint256[] memory)\n {\n AccumulatingArray.Data memory accumulated = AccumulatingArray.create(length);\n for (uint256 i = 0; i < arrays.length; i++) {\n accumulated.add(arrays[i]);\n }\n return accumulated.items;\n }\n\n // Adds single element arrays as individual items\n function accumulateWithIndividuals(uint256[][] memory arrays, uint256 length)\n public\n pure\n returns (uint256[] memory)\n {\n AccumulatingArray.Data memory accumulated = AccumulatingArray.create(length);\n for (uint256 i = 0; i < arrays.length; i++) {\n if (arrays[i].length == 1) {\n accumulated.add(arrays[i][0]);\n } else {\n accumulated.add(arrays[i]);\n }\n }\n return accumulated.items;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From 2baae46fc7b3c83658b40b5ecab0b209edd1b19a Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 30 Nov 2022 20:12:30 +0100 Subject: [PATCH 5/5] Add arbitrum goerli asset library toml file --- README.md | 11 +++-- .../cape_v2_official_assets.toml | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 wallet/official_assets/cape_v2_official_assets.toml diff --git a/README.md b/README.md index a6f35522..f9415258 100644 --- a/README.md +++ b/README.md @@ -600,9 +600,14 @@ generator to authenticate itself in various ways: assets in the official asset library. You must also have a TOML file specifying the assets to create. There are already TOML files for -the official asset libraries for [the Goerli deployment](wallet/official_assets/cape_v1_official_assets.toml) -and [the local demo](wallet/official_assets/cape_demo_local_official_assets.toml). These can always -be modified or copied to create fully customizable asset libraries. +the official asset libraries for + +- [the Goerli deployment](wallet/official_assets/cape_v1_official_assets.toml) +- [the local demo](wallet/official_assets/cape_demo_local_official_assets.toml) +- [the Arbitrum goerli deployment](wallet/official_assets/cape_v2_official_assets.toml) + +These can always be modified or copied to create fully customizable asset +libraries. Then, the command would look like diff --git a/wallet/official_assets/cape_v2_official_assets.toml b/wallet/official_assets/cape_v2_official_assets.toml new file mode 100644 index 00000000..22cc2760 --- /dev/null +++ b/wallet/official_assets/cape_v2_official_assets.toml @@ -0,0 +1,41 @@ + +# Copyright (c) 2022 Espresso Systems (espressosys.com) +# This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library. +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with this program. If not, see . + +# The official asset library for CAPE v1 on Goerli + +[[assets]] +symbol = 'CAPE' +type = 'native' + +[[assets]] +symbol = 'capedWETH' +description = 'Wrapped WETH on Goerli' +icon = 'icons/WGTH.png' +type = 'wrapped' +contract = '0x4F1D9E040cf28A522ec79951cDb7B55c8aE4744E' +viewing_key = 'AUDPUBKEY~a0J7uXJcUxDnSONQamzF6bZXpTrvPeKHCGKLsFx9tQiI' + +[[assets]] +symbol = 'capedDAI' +description = 'Wrapped DAI' +icon = 'icons/DAI.png' +type = 'wrapped' +contract = '0xBeec50ed16E3559afCD582cC98ed2b5F5DcA189E' +# The viewing key is maintained by Espresso, but would belong to Maker Foundation in a real deployment +viewing_key = 'AUDPUBKEY~z1xFfj2B6dTdUn1tcyexZd8v8foMPDJibT8hrmXXkAhx' + +[[assets]] +symbol = 'capedUSDC' +description = 'Wrapped USDC' +icon = 'icons/USDC.png' +type = 'wrapped' +contract = '0x9A4f4Ee35a8FfEE459B3187A372d422790fc8aAB' +# The viewing key is maintained by Espresso, but would belong to Circle in a real deployment +viewing_key = 'AUDPUBKEY~A1EVmqt8rZc6ibPolJ0gVI-cUxTOark5L9e9TTEDt6G-' +# The freezing key is maintained by Espresso, but would belong to Circle in a real deployment +freezing_key = 'FREEZEPUBKEY~iCR07O3hlKc25lFd467Eqs3ZAF1ME1wT5aW9VqHa14e2'