diff --git a/.github/workflows/pinata-upload.yml b/.github/workflows/pinata-upload.yml index 85de767..d6c292a 100644 --- a/.github/workflows/pinata-upload.yml +++ b/.github/workflows/pinata-upload.yml @@ -22,7 +22,7 @@ jobs: run: | curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash export PATH="$HOME/.nargo/bin:$PATH" - noirup --version 1.0.0-beta.15 + noirup --version 1.0.0-beta.16 echo "$HOME/.nargo/bin" >> $GITHUB_PATH - name: Install bb (Barretenberg) @@ -43,7 +43,7 @@ jobs: env: VITE_GITHUB_ACTION_BUILD_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} VITE_DOMAIN: ${{ github.ref == 'refs/heads/main' && 'https://commbank.eth.limo' || 'https://dev.commbank.eth.limo' }} - VITE_DEFAULT_CHAIN_ID: ${{ github.ref == 'refs/heads/main' && '1' || '11155111' }} + VITE_DEFAULT_CHAIN_ID: ${{ github.ref == 'refs/heads/main' && '1' || '421614' }} run: | export PNPM_HOME="$HOME/.local/share/pnpm" export PATH="$PNPM_HOME:$PATH" diff --git a/.github/workflows/test-client-v2-build.yml b/.github/workflows/test-client-v2-build.yml index 72951d4..2a0e97c 100644 --- a/.github/workflows/test-client-v2-build.yml +++ b/.github/workflows/test-client-v2-build.yml @@ -21,7 +21,7 @@ jobs: run: | curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash export PATH="$HOME/.nargo/bin:$PATH" - noirup --version 1.0.0-beta.15 + noirup --version 1.0.0-beta.16 echo "$HOME/.nargo/bin" >> $GITHUB_PATH - name: Install bb (Barretenberg) diff --git a/CLAUDE.md b/CLAUDE.md index a8a6157..99b223f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,7 @@ CommBank.eth is a privacy-enabled DeFi platform that facilitates private transfe ## Monorepo Structure -This is a Bun workspace monorepo with the following packages: +This is a pnpm workspace monorepo with the following packages: ### `client/` - Next.js Frontend (Primary) @@ -79,7 +79,7 @@ This is a Bun workspace monorepo with the following packages: ### `circuits/` - Zero-Knowledge Circuits (Noir) -- **Tech Stack:** Noir language v1.0.0-beta.15 +- **Tech Stack:** Noir language v1.0.0-beta.16 - **Purpose:** ZK-SNARK circuit definitions for private operations - **Circuits:** - `deposit/` - Prove deposit commitment without revealing amount @@ -124,58 +124,56 @@ This is a Bun workspace monorepo with the following packages: ```bash # Install all dependencies -bun install +pnpm install # Format all code -bun run format +pnpm run format # Check formatting -bun run format:check +pnpm run format:check # Lint all code -bun run lint +pnpm run lint # Fix lint errors -bun run lint:fix +pnpm run lint:fix # Start development (runs client by default) -bun run dev +pnpm run dev # Build client -bun run build +pnpm run build # Build contracts and generate verifiers -bun run build-contracts +pnpm run build-contracts ``` ### Client (Next.js) ```bash cd client -bun run dev # Start dev server on localhost:3000 -bun run build # Production build -bun run start # Run production build -bun run lint # Next.js linting +pnpm run dev # Start dev server on localhost:3000 +pnpm run build # Production build +pnpm run start # Run production build +pnpm run lint # Next.js linting ``` ### client (Vite + React Router) ```bash cd client -bun run dev # Start Vite dev server -bun run build # Build with TypeScript + Vite -bun run preview # Preview production build -bun run lint # ESLint check +pnpm run dev # Start Vite dev server +pnpm run build # Build with TypeScript + Vite +pnpm run preview # Preview production build +pnpm run lint # ESLint check ``` ### Contracts ```bash cd contracts -bun run build # Build verifiers from circuits (primary build command) -bun run build-bb # Compile Noir circuits to bytecode -bun run build-ipfs # Build and upload to IPFS -bun run deploy # Deploy contracts (ts-node scripts/deploy.ts) +pnpm run build # Build verifiers from circuits (primary build command) +pnpm run build-bb # Compile Noir circuits to bytecode # Testing npx hardhat test # Run all tests @@ -278,7 +276,7 @@ const proof = await deposit.depositNoir.generateProof(inputs); - **Config:** `eslint.config.mjs` at root (modern flat config) - **Rules:** TypeScript + Prettier plugin integration - **Ignored Paths:** node_modules, dist, build, .next, out -- **Run:** `bun run lint` and `bun run lint:fix` +- **Run:** `pnpm run lint` and `pnpm run lint:fix` ### Prettier Configuration @@ -289,7 +287,7 @@ const proof = await deposit.depositNoir.generateProof(inputs); - Single quotes: false (use double quotes) - Print width: 80 characters - Tab width: 2 spaces -- **Run:** `bun run format` and `bun run format:check` +- **Run:** `pnpm run format` and `pnpm run format:check` ### TypeScript Configuration @@ -387,7 +385,7 @@ const proof = await deposit.depositNoir.generateProof(inputs); ### Circuits -- **Language:** Noir v1.0.0-beta.15 +- **Language:** Noir v1.0.0-beta.16 - **Dependencies:** Poseidon (noir-lang/poseidon) - **Proving:** Aztec Barretenberg backend via bb.js @@ -402,7 +400,7 @@ const proof = await deposit.depositNoir.generateProof(inputs); - `PRIVATE_KEY` - Deployment account key - `DEMO_MNEMONIC_ALICE` - Test wallet mnemonic -**Auto-loaded by Bun:** Use environment variables directly; Bun loads `.env` automatically +**Loading ENV:** Use dotenv or configure your shell to load `.env` files ## Testing Overview @@ -437,8 +435,8 @@ const proof = await deposit.depositNoir.generateProof(inputs); ### Running client Locally 1. `cd client` -2. `bun install` (if dependencies changed) -3. `bun run dev` - Opens at http://localhost:5173 +2. `pnpm install` (if dependencies changed) +3. `pnpm run dev` - Opens at http://localhost:5173 4. Changes auto-reload (Vite HMR) ### Debugging Proofs @@ -451,14 +449,14 @@ const proof = await deposit.depositNoir.generateProof(inputs); ### Deploying to Testnets 1. Ensure proper ENV variables are set -2. Verify circuit artifacts are built (`bun run build-contracts`) +2. Verify circuit artifacts are built (`pnpm run build-contracts`) 3. Run: `npx hardhat run scripts/deploy.ts --network ` 4. Network names: hardhat, mainnet, arbitrumOne, base ### Working with Shared Package - Always import as `shared-package/*` (not relative paths) -- Changes to shared require re-running `bun install` in dependent packages +- Changes to shared require re-running `pnpm install` in dependent packages - Shared uses workspace:\* to link to contracts package ## Notable Design Decisions @@ -468,7 +466,7 @@ const proof = await deposit.depositNoir.generateProof(inputs); 3. **Encrypted Notes:** Notes encrypted with user's public key, enabling note passing without on-chain storage 4. **Two Keys:** Signing key (public key) and owning key (poseidon hash) allow efficient ZK proofs vs on-chain encryption 5. **TypeChain Integration:** Type-safe contract ABIs prevent runtime errors during tests -6. **Bun Runtime:** Faster compilation and bundling for TS/TSX; better dev experience than Node.js +6. **pnpm Workspaces:** Efficient disk space usage with symlinked node_modules; strict dependency resolution ## Known Limitations & WIPs diff --git a/README.md b/README.md index ab4d383..24ada1d 100755 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ # commbank.eth -### the bank you don't have to trust +### open source, privacy enhancing financial technologies ## Components -- `client*/`: the commbank.eth web app (currently 2 versions) -- `contracts/`: the EVM smart contracts required to facilitate private transfers -- `circuits/`: an implementation of a Multi Asset Shield Pool with `poseidon2` as the merkle tree hash function -- `indexer/`: the indexer that makes the merkle tree data available easier +- `client/`: the commbank.eth web app deployed to `https://commbank.eth.limo` +- `contracts/`: the EVM smart contracts required to facilitate Private Unstoppable Money +- `circuits/`: Private Unstoppable Money Zero Knowledge circuits +- `indexer/`: a data indexer used to cache Private Unstoppable Money transactions more efficiently +- `relayer/`: an expressJS based backend that forwards RPC requests and works as a transaction relayer ## Development diff --git a/circuits/deposit/Nargo.toml b/circuits/deposit/Nargo.toml index d6f12ec..5d9e49f 100755 --- a/circuits/deposit/Nargo.toml +++ b/circuits/deposit/Nargo.toml @@ -5,3 +5,4 @@ authors = [""] [dependencies] poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } +pum_lib = { path = '../pum_lib' } \ No newline at end of file diff --git a/circuits/deposit/src/main.nr b/circuits/deposit/src/main.nr index d88a060..446b601 100755 --- a/circuits/deposit/src/main.nr +++ b/circuits/deposit/src/main.nr @@ -1,11 +1,4 @@ -use poseidon; - -fn calculate_leaf(asset_id: Field, asset_amount: Field, owner: Field, secret: Field) -> Field { - let leaf_hash = - poseidon::poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4); - - leaf_hash -} +use pum_lib; fn main( hash: pub Field, @@ -14,7 +7,7 @@ fn main( owner: Field, secret: Field, ) { - let reconstructed_leaf = calculate_leaf(asset_id, asset_amount, owner, secret); + let reconstructed_leaf = pum_lib::calculate_leaf(asset_id, asset_amount, owner, secret); assert(reconstructed_leaf == hash); } diff --git a/circuits/warp/Nargo.toml b/circuits/pum_lib/Nargo.toml old mode 100755 new mode 100644 similarity index 79% rename from circuits/warp/Nargo.toml rename to circuits/pum_lib/Nargo.toml index 38d523c..92f44ca --- a/circuits/warp/Nargo.toml +++ b/circuits/pum_lib/Nargo.toml @@ -1,7 +1,7 @@ [package] -name = "warp" -type = "bin" +name = "pum_lib" authors = [""] +type = "lib" [dependencies] poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } diff --git a/circuits/pum_lib/src/lib.nr b/circuits/pum_lib/src/lib.nr new file mode 100644 index 0000000..94608a3 --- /dev/null +++ b/circuits/pum_lib/src/lib.nr @@ -0,0 +1,48 @@ +use poseidon; +use poseidon::poseidon2; + +global HEIGHT: u32 = 12; + +pub fn calculate_leaf(asset_id: Field, asset_amount: Field, owner: Field, secret: Field) -> Field { + let leaf_hash = + poseidon::poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4); + + leaf_hash +} + +pub fn compute_merkle_root( + leaf: Field, + path: [Field; HEIGHT - 1], + path_indices: [Field; HEIGHT - 1], +) -> Field { + let mut current = leaf; + for i in 0..HEIGHT - 1 { + let path_bit = path_indices[i]; + let (hash_left, hash_right) = if path_bit == 0 { + (path[i], current) + } else { + (current, path[i]) + }; + current = poseidon2::Poseidon2::hash([hash_left, hash_right], 2); + } + current +} + +pub fn compute_nullifier( + leaf_index: Field, + owner: Field, + secret: Field, + asset_id: Field, + asset_amount: Field, +) -> Field { + poseidon2::Poseidon2::hash([leaf_index, owner, secret, asset_id, asset_amount], 5) +} + +pub fn reconstruct_leaf( + asset_id: Field, + asset_amount: Field, + owner: Field, + secret: Field, +) -> Field { + poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4) +} diff --git a/circuits/transfer/Nargo.toml b/circuits/transfer/Nargo.toml index a3f89ec..c7af12f 100755 --- a/circuits/transfer/Nargo.toml +++ b/circuits/transfer/Nargo.toml @@ -5,3 +5,4 @@ authors = [""] [dependencies] poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } +pum_lib = { path = '../pum_lib' } \ No newline at end of file diff --git a/circuits/transfer/src/main.nr b/circuits/transfer/src/main.nr index da2a763..eb1d4e3 100755 --- a/circuits/transfer/src/main.nr +++ b/circuits/transfer/src/main.nr @@ -1,10 +1,10 @@ -global HEIGHT: u32 = 12; -global NOTE_COUNT: u32 = 3; - use poseidon::poseidon2::{self, Poseidon2Hasher}; - +use pum_lib::{self, compute_merkle_root, compute_nullifier, reconstruct_leaf}; use std::{collections::map::HashMap, hash::BuildHasherDefault}; +global HEIGHT: u32 = 12; +global NOTE_COUNT: u32 = 3; + struct InputNote { asset_id: Field, asset_amount: Field, @@ -23,38 +23,6 @@ struct OutputNote { asset_amount: Field, } -fn compute_merkle_root( - leaf: Field, - path: [Field; HEIGHT - 1], - path_indices: [Field; HEIGHT - 1], -) -> Field { - let mut current = leaf; - for i in 0..HEIGHT - 1 { - let path_bit = path_indices[i]; - let (hash_left, hash_right) = if path_bit == 0 { - (path[i], current) - } else { - (current, path[i]) - }; - current = poseidon2::Poseidon2::hash([hash_left, hash_right], 2); - } - current -} - -fn compute_nullifier( - leaf_index: Field, - owner: Field, - secret: Field, - asset_id: Field, - asset_amount: Field, -) -> Field { - poseidon2::Poseidon2::hash([leaf_index, owner, secret, asset_id, asset_amount], 5) -} - -fn reconstruct_leaf(asset_id: Field, asset_amount: Field, owner: Field, secret: Field) -> Field { - poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4) -} - fn main( root: pub Field, input_notes: [InputNote; NOTE_COUNT], diff --git a/circuits/transfer_external/Nargo.toml b/circuits/transfer_external/Nargo.toml new file mode 100644 index 0000000..32ce7ae --- /dev/null +++ b/circuits/transfer_external/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "transfer_external" +type = "bin" +authors = [""] + +[dependencies] +poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } +pum_lib = { path = '../pum_lib' } \ No newline at end of file diff --git a/circuits/transfer_external/src/main.nr b/circuits/transfer_external/src/main.nr new file mode 100644 index 0000000..4dbf96e --- /dev/null +++ b/circuits/transfer_external/src/main.nr @@ -0,0 +1,124 @@ +use poseidon::poseidon2::{self, Poseidon2Hasher}; +use pum_lib::{self, compute_merkle_root, compute_nullifier, reconstruct_leaf}; +use std::{collections::map::HashMap, hash::BuildHasherDefault}; + +global HEIGHT: u32 = 12; +global NOTE_COUNT: u32 = 3; + +struct InputNote { + asset_id: Field, + asset_amount: Field, + owner: Field, + owner_secret: Field, + secret: Field, + leaf_index: Field, + path: [Field; HEIGHT - 1], + path_indices: [Field; HEIGHT - 1], +} + +struct OutputNote { + owner: Field, + secret: Field, + asset_id: Field, + asset_amount: Field, + external_address: Field, +} + +fn main( + root: pub Field, + input_notes: [InputNote; NOTE_COUNT], + output_notes: [OutputNote; NOTE_COUNT], + nullifiers: pub [Field; NOTE_COUNT], + output_hashes: pub [Field; NOTE_COUNT], + exit_assets: pub [Field; NOTE_COUNT], + exit_amounts: pub [Field; NOTE_COUNT], + exit_addresses: pub [Field; NOTE_COUNT], + exit_address_hashes: pub [Field; NOTE_COUNT], +) { + let mut inputs_map: HashMap> = + HashMap::default(); + let mut outputs_map: HashMap> = + HashMap::default(); + + // Process input notes - validate ownership, nullifiers, and merkle membership + for i in 0..NOTE_COUNT - 1 { + if input_notes[i].asset_amount != 0 { + // check owner is correct + let owner_pub_key = poseidon2::Poseidon2::hash([input_notes[i].owner_secret], 1); + assert(owner_pub_key == input_notes[i].owner); + + // check nullifier is correct + let reconstructed_nullifier = compute_nullifier( + input_notes[i].leaf_index, + input_notes[i].owner, + input_notes[i].secret, + input_notes[i].asset_id, + input_notes[i].asset_amount, + ); + assert(reconstructed_nullifier == nullifiers[i]); + + // check merkle membership + let reconstructed_leaf = reconstruct_leaf( + input_notes[i].asset_id, + input_notes[i].asset_amount, + input_notes[i].owner, + input_notes[i].secret, + ); + let reconstructed_merkle_root = compute_merkle_root( + reconstructed_leaf, + input_notes[i].path, + input_notes[i].path_indices, + ); + assert(reconstructed_merkle_root == root); + + // track input amounts + let current_asset_amount = inputs_map.get(input_notes[i].asset_id).unwrap_or(0); + inputs_map.insert( + input_notes[i].asset_id, + current_asset_amount + input_notes[i].asset_amount, + ); + } + } + + // Process output notes - handle both internal transfers and external withdrawals + for i in 0..NOTE_COUNT - 1 { + if output_notes[i].asset_amount != 0 { + if output_notes[i].external_address != 0 { + // This is a withdrawal - validate exit parameters + assert(exit_assets[i] == output_notes[i].asset_id); + assert(exit_amounts[i] == output_notes[i].asset_amount); + assert(exit_addresses[i] == output_notes[i].external_address); + + // Prevent frontrunning by hashing the exit address + let frontrun_hash = poseidon2::Poseidon2::hash([exit_addresses[i]], 1); + assert(frontrun_hash == exit_address_hashes[i]); + } else { + // This is an internal transfer - validate output hash + let output_leaf_note = reconstruct_leaf( + output_notes[i].asset_id, + output_notes[i].asset_amount, + output_notes[i].owner, + output_notes[i].secret, + ); + assert(output_leaf_note == output_hashes[i]); + } + + // track output amounts (both internal and external) + let current_asset_amount = outputs_map.get(output_notes[i].asset_id).unwrap_or(0); + outputs_map.insert( + output_notes[i].asset_id, + current_asset_amount + output_notes[i].asset_amount, + ); + } + } + + // Ensure input and output amounts match for each asset + assert(inputs_map.len() == outputs_map.len()); + + for i in 0..NOTE_COUNT - 1 { + assert( + inputs_map.get(input_notes[i].asset_id).unwrap_or(0) + == outputs_map.get(input_notes[i].asset_id).unwrap_or(0), + ); + } +} diff --git a/circuits/warp/src/main.nr b/circuits/warp/src/main.nr deleted file mode 100755 index 38f5977..0000000 --- a/circuits/warp/src/main.nr +++ /dev/null @@ -1,240 +0,0 @@ -global HEIGHT: u32 = 12; -global NOTE_COUNT: u32 = 3; - -use poseidon::poseidon2::{self, Poseidon2Hasher}; -use std::{collections::map::HashMap, hash::BuildHasherDefault}; - -struct InputNote { - asset_id: Field, - asset_amount: Field, - owner: Field, - owner_secret: Field, - secret: Field, - leaf_index: Field, - path: [Field; HEIGHT - 1], - path_indices: [Field; HEIGHT - 1], -} - -struct OutputNote { - owner: Field, - secret: Field, - asset_id: Field, - asset_amount: Field, -} - -fn compute_merkle_root( - leaf: Field, - path: [Field; HEIGHT - 1], - path_indices: [Field; HEIGHT - 1], -) -> Field { - let mut current = leaf; - for i in 0..HEIGHT - 1 { - let path_bit = path_indices[i]; - let (hash_left, hash_right) = if path_bit == 0 { - (path[i], current) - } else { - (current, path[i]) - }; - current = poseidon2::Poseidon2::hash([hash_left, hash_right], 2); - } - current -} - -fn compute_nullifier( - leaf_index: Field, - owner: Field, - secret: Field, - asset_id: Field, - asset_amount: Field, -) -> Field { - poseidon2::Poseidon2::hash([leaf_index, owner, secret, asset_id, asset_amount], 5) -} - -fn reconstruct_leaf(asset_id: Field, asset_amount: Field, owner: Field, secret: Field) -> Field { - poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4) -} - -fn main( - root: pub Field, - input_notes: [InputNote; NOTE_COUNT], - output_notes: [OutputNote; NOTE_COUNT], - nullifiers: pub [Field; NOTE_COUNT], - output_hashes: pub [Field; NOTE_COUNT], - stargate_assets: pub [Field; NOTE_COUNT], - stargate_amounts: pub [Field; NOTE_COUNT], -) { - let mut inputs_map: HashMap> = - HashMap::default(); - let mut outputs_map: HashMap> = - HashMap::default(); - - for i in 0..NOTE_COUNT - 1 { - // if note is not empty - if input_notes[i].asset_amount != 0 { - // check owner is correct - let owner_pub_key = poseidon2::Poseidon2::hash([input_notes[i].owner_secret], 1); - assert(owner_pub_key == input_notes[i].owner); - - // check nullifier is correct - let reconstructed_nullifier = compute_nullifier( - input_notes[i].leaf_index, - input_notes[i].owner, - input_notes[i].secret, - input_notes[i].asset_id, - input_notes[i].asset_amount, - ); - assert(reconstructed_nullifier == nullifiers[i]); - - // check merkle membership - let reconstructed_leaf = reconstruct_leaf( - input_notes[i].asset_id, - input_notes[i].asset_amount, - input_notes[i].owner, - input_notes[i].secret, - ); - let reconstructed_merkle_root = compute_merkle_root( - reconstructed_leaf, - input_notes[i].path, - input_notes[i].path_indices, - ); - assert(reconstructed_merkle_root == root); - - let current_asset_amount = inputs_map.get(input_notes[i].asset_id).unwrap_or(0); - inputs_map.insert( - input_notes[i].asset_id, - current_asset_amount + input_notes[i].asset_amount, - ); - } - - if output_notes[i].asset_amount != 0 { - let output_leaf_note = reconstruct_leaf( - output_notes[i].asset_id, - output_notes[i].asset_amount, - output_notes[i].owner, - output_notes[i].secret, - ); - assert(output_leaf_note == output_hashes[i]); - - // output note amount must equal stargate_asset and stargate_amount - if stargate_assets[i] != 0 { - assert(stargate_assets[i] == output_notes[i].asset_id); - } - - if stargate_amounts[i] != 0 { - assert(stargate_amounts[i] == output_notes[i].asset_amount); - } - - let current_asset_amount = outputs_map.get(output_notes[i].asset_id).unwrap_or(0); - outputs_map.insert( - output_notes[i].asset_id, - current_asset_amount + output_notes[i].asset_amount, - ) - } - } - - // check input and output asset keys are equal - assert(inputs_map.len() == outputs_map.len()); - - for i in 0..NOTE_COUNT - 1 { - assert( - inputs_map.get(input_notes[i].asset_id).unwrap_or(0) - == outputs_map.get(input_notes[i].asset_id).unwrap_or(0), - ); - } -} - -#[test] -fn test_main() { - let root = 4221110344891604176205088962198904729260430126413313722462390172704999703195; - let asset_id = 1096978651789611665652906124278561787240579697095; - let asset_amount = 5; - let owner = 10812186542955647827474372651967207045861174805371180171801345448553285386806; - let owner_secret = - 10036677144260647934022413515521823129584317400947571241312859176539726523915; - let secret = 2389312107716289199307843900794656424062350252250388738019021107824217896920; - - let nullifier = 3889730504789135603011318287331683111639714777739573239289638917879152395137; - - let leaf_index = 0; - - // this is the empty tree after the hash 9194668555912557146241026266248928483973497222045579120388006164958747201268 - // is inserted at index 0 - let leaf = 15877031116292595040191017675338240539290338653409019794000313907399651592164; - - let path = [ - 13640659629327953230197633652529006805891215582818597888084863207147219313784, - 19984673905358619496530873554532699316557532969285237470013525856790495658245, - 16054022188397161938956278061878851932956033792728066452148841350372709856325, - 5088416905632566847489144423785449560596474956704206833561295200206123281740, - 7133742548945823648162717112853949322814446130740022056636610844051076979955, - 15996976533936258369996214630141201173712053425083354410411158951568838211277, - 12856765864455281126306545538308148448222111081433610923407492298111988109924, - 4407863489559565071205165471845081321675763465852502126771740970311657294198, - 20448284296610764092326252358036828964180135505542140040145855516028834425624, - 7022843789375185322738689530892530453984779704784378294646894048972162829679, - 10906054357754859492130109809751867122631984061959461434096281674698176679467, - ]; - let path_indices = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - - let recon_merkle_root = compute_merkle_root(leaf, path, path_indices); - - let input_note: InputNote = InputNote { - asset_id, - asset_amount, - owner, - owner_secret, - secret, - leaf_index, - path, - path_indices, - }; - - let nullifiers = [nullifier, 0, 0]; - let empty_output_note: OutputNote = - OutputNote { owner: 0, secret: 0, asset_id: 0, asset_amount: 0 }; - let empty_input_note: InputNote = InputNote { - asset_id: 0, - asset_amount: 0, - owner: 0, - owner_secret: 0, - secret: 0, - leaf_index: 0, - path: [0; HEIGHT - 1], - path_indices: [0; HEIGHT - 1], - }; - - let input_notes = [input_note, empty_input_note, empty_input_note]; - - let alice_output_note: OutputNote = OutputNote { - owner: 10812186542955647827474372651967207045861174805371180171801345448553285386806, - secret: 19536471094918068928039225564664574556680178861106125446000998678966251111926, - asset_id: 1096978651789611665652906124278561787240579697095, - asset_amount: 3, - }; - let alice_output_hash = - 8576856452718270547402366094981334736141859948414539161051536617849336979212; - - let bob_output_note: OutputNote = OutputNote { - owner: 6868973719921785236727144517868768664734231208097695530688003960085654392226, - secret: 3957740128091467064337395812164919758932045173069261808814882570720300029469, - asset_id: 1096978651789611665652906124278561787240579697095, - asset_amount: 2, - }; - let bob_output_hash = - 4033300113401483633011546954450009404136112133461230452107665732116532508739; - let output_notes = [alice_output_note, bob_output_note, empty_output_note]; - let output_hashes = [alice_output_hash, bob_output_hash, 0]; - - let stargate_assets = [0, bob_output_note.asset_id, 0]; - let startgate_amounts = [0, bob_output_note.asset_amount, 0]; - - main( - root, - input_notes, - output_notes, - nullifiers, - output_hashes, - stargate_assets, - startgate_amounts, - ); -} diff --git a/circuits/withdraw/Nargo.toml b/circuits/withdraw/Nargo.toml index 34a42ff..63013d3 100755 --- a/circuits/withdraw/Nargo.toml +++ b/circuits/withdraw/Nargo.toml @@ -5,3 +5,4 @@ authors = [""] [dependencies] poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } +pum_lib = { path = '../pum_lib' } diff --git a/circuits/withdraw/src/main.nr b/circuits/withdraw/src/main.nr index 301abca..708ff55 100755 --- a/circuits/withdraw/src/main.nr +++ b/circuits/withdraw/src/main.nr @@ -1,8 +1,9 @@ +use poseidon::poseidon2; +use pum_lib::{self, compute_merkle_root, compute_nullifier, reconstruct_leaf}; + global HEIGHT: u32 = 12; global NOTE_COUNT: u32 = 3; -use poseidon::poseidon2; - struct InputNote { asset_id: Field, asset_amount: Field, @@ -14,38 +15,6 @@ struct InputNote { path_indices: [Field; HEIGHT - 1], } -fn compute_merkle_root( - leaf: Field, - path: [Field; HEIGHT - 1], - path_indices: [Field; HEIGHT - 1], -) -> Field { - let mut current = leaf; - for i in 0..HEIGHT - 1 { - let path_bit = path_indices[i]; - let (hash_left, hash_right) = if path_bit == 0 { - (path[i], current) - } else { - (current, path[i]) - }; - current = poseidon2::Poseidon2::hash([hash_left, hash_right], 2); - } - current -} - -fn compute_nullifier( - leaf_index: Field, - owner: Field, - secret: Field, - asset_id: Field, - asset_amount: Field, -) -> Field { - poseidon2::Poseidon2::hash([leaf_index, owner, secret, asset_id, asset_amount], 5) -} - -fn reconstruct_leaf(asset_id: Field, asset_amount: Field, owner: Field, secret: Field) -> Field { - poseidon2::Poseidon2::hash([asset_id, asset_amount, owner, secret], 4) -} - fn main( root: pub Field, input_notes: [InputNote; NOTE_COUNT], diff --git a/client/.gitignore b/client/.gitignore index a547bf3..f52343a 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +*storybook.log +storybook-static diff --git a/client/.storybook/main.ts b/client/.storybook/main.ts new file mode 100644 index 0000000..172a202 --- /dev/null +++ b/client/.storybook/main.ts @@ -0,0 +1,52 @@ +import type { StorybookConfig } from "@storybook/react-vite"; +import path from "path"; +import { fileURLToPath } from "url"; + +// ESM equivalent of __dirname +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const config: StorybookConfig = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@chromatic-com/storybook", + "@storybook/addon-vitest", + "@storybook/addon-a11y", + "@storybook/addon-docs", + "@storybook/addon-onboarding", + ], + framework: "@storybook/react-vite", + viteFinal: async (viteConfig) => { + const srcPath = path.resolve(__dirname, "../src"); + const mockAuthPath = path.resolve( + __dirname, + "../src/stories/mocks/auth-provider.mock.tsx", + ); + + return { + ...viteConfig, + resolve: { + ...viteConfig.resolve, + // Use array format to guarantee order - first match wins + alias: [ + // Mock auth-provider FIRST (most specific) + { + find: "@/_providers/auth-provider", + replacement: mockAuthPath, + }, + // Then the general @ alias + { + find: "@", + replacement: srcPath, + }, + // Pino browser shim + { + find: "pino", + replacement: "pino/browser.js", + }, + ], + }, + }; + }, +}; +export default config; diff --git a/client/.storybook/preview.tsx b/client/.storybook/preview.tsx new file mode 100644 index 0000000..ef76403 --- /dev/null +++ b/client/.storybook/preview.tsx @@ -0,0 +1,48 @@ +import type { Preview, Decorator } from "@storybook/react-vite"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import React from "react"; +import "../src/index.css"; + +// Create a fresh QueryClient for stories +const createTestQueryClient = () => + new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false, + }, + }, + }); + +// Global decorator to provide QueryClient for React Query hooks +const withQueryClient: Decorator = (Story) => { + const queryClient = React.useMemo(() => createTestQueryClient(), []); + return ( + + + + ); +}; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + + a11y: { + // 'todo' - show a11y violations in the test UI only + // 'error' - fail CI on a11y violations + // 'off' - skip a11y checks entirely + test: "todo", + }, + }, + + // Global decorators applied to all stories + decorators: [withQueryClient], +}; + +export default preview; diff --git a/client/.storybook/vitest.setup.ts b/client/.storybook/vitest.setup.ts new file mode 100644 index 0000000..fd7ac45 --- /dev/null +++ b/client/.storybook/vitest.setup.ts @@ -0,0 +1,7 @@ +import * as a11yAddonAnnotations from "@storybook/addon-a11y/preview"; +import { setProjectAnnotations } from "@storybook/react-vite"; +import * as projectAnnotations from "./preview"; + +// This is an important step to apply the right configuration when testing your stories. +// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations +setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]); diff --git a/client/components.json b/client/components.json index 2357e03..504d16c 100644 --- a/client/components.json +++ b/client/components.json @@ -12,11 +12,11 @@ }, "iconLibrary": "lucide", "aliases": { - "components": "@/components", + "components": "@/_components", "utils": "@/lib/utils", - "ui": "@/components/ui", + "ui": "@/_components/ui", "lib": "@/lib", - "hooks": "@/hooks" + "hooks": "@/_hooks" }, "registries": {} } diff --git a/client/package.json b/client/package.json index f98556d..02ce592 100644 --- a/client/package.json +++ b/client/package.json @@ -6,22 +6,24 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "build-ipfs": "bun run build && bunx tsx scripts/deploy-to-ipfs.ts", - "deploy-ipfs": "bunx tsx scripts/deploy-to-ipfs.ts", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "dependencies": { "@aztec/bb.js": "3.0.0-nightly.20251104", - "@noir-lang/noir_js": "1.0.0-beta.15", + "@noir-lang/noir_js": "1.0.0-beta.16", + "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-query": "^5.90.5", @@ -33,12 +35,14 @@ "ethers": "^6.15.0", "framer-motion": "^12.23.24", "lucide-react": "^0.548.0", + "qrcode.react": "^4.2.0", "react": "^19.1.1", "react-dom": "^19.1.1", "react-helmet": "^6.1.0", "react-hook-form": "^7.66.0", "react-markdown": "^10.1.0", "react-router-dom": "^7.9.4", + "recharts": "2.15.4", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "shared": "workspace:*", @@ -47,22 +51,34 @@ "tailwindcss": "^4.1.16" }, "devDependencies": { + "@chromatic-com/storybook": "^5.0.0", "@eslint/js": "^9.36.0", + "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11", + "@storybook/addon-onboarding": "^10.1.11", + "@storybook/addon-vitest": "^10.1.11", + "@storybook/react-vite": "^10.1.11", "@types/node": "^24.9.2", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", + "@vitest/browser-playwright": "^4.0.16", + "@vitest/coverage-v8": "^4.0.16", "axios": "^1.7.9", "eslint": "^9.36.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.22", + "eslint-plugin-storybook": "^10.1.11", "form-data": "^4.0.0", "globals": "^16.4.0", + "playwright": "^1.57.0", + "storybook": "^10.1.11", "tsx": "^4.19.2", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7", - "vite-plugin-node-polyfills": "^0.24.0" + "vite-plugin-node-polyfills": "^0.24.0", + "vitest": "^4.0.16" } } diff --git a/client/public/audd-logo.png b/client/public/audd-logo.png new file mode 100644 index 0000000..eb4a9aa Binary files /dev/null and b/client/public/audd-logo.png differ diff --git a/client/public/eth-logo.png b/client/public/eth-logo.png new file mode 100644 index 0000000..6176fa6 Binary files /dev/null and b/client/public/eth-logo.png differ diff --git a/client/public/link-logo.png b/client/public/link-logo.png new file mode 100644 index 0000000..63a1f35 Binary files /dev/null and b/client/public/link-logo.png differ diff --git a/client/public/usdc-logo.png b/client/public/usdc-logo.png new file mode 100644 index 0000000..1ba777f Binary files /dev/null and b/client/public/usdc-logo.png differ diff --git a/client/scripts/README.md b/client/scripts/README.md deleted file mode 100644 index 9b78b4f..0000000 --- a/client/scripts/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# client Scripts - -## Deploy to IPFS - -This script builds the client application and uploads it to a local IPFS node. - -### Prerequisites - -- IPFS node running at `http://localhost:6969` -- Built dist directory (automatically created by `build-ipfs` command) - -### Usage - -From the project root: - -```bash -bun run build-ipfs -``` - -Or from the client directory: - -```bash -cd client -bun run build-ipfs # Build and upload -bun run deploy-ipfs # Upload only (requires existing build) -``` - -### What it does - -1. Compiles TypeScript and builds the Vite application -2. Reads all files from the `dist/` directory -3. Uploads them to your local IPFS node at `localhost:6969` -4. Returns the IPFS hash (CID) of the uploaded content - -### Output - -The script will output: - -- ✅ Upload successful! -- 📍 IPFS Hash: `QmXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` -- 🌐 Local Gateway URL: `http://localhost:6969/ipfs/QmXXX...` -- 🌐 Public Gateway URL: `https://ipfs.io/ipfs/QmXXX...` - -### Configuration - -To change the IPFS node URL, edit the `IPFS_API_URL` constant in `scripts/deploy-to-ipfs.ts`: - -```typescript -const IPFS_API_URL = "http://localhost:6969"; -``` diff --git a/client/scripts/deploy-to-ipfs.ts b/client/scripts/deploy-to-ipfs.ts deleted file mode 100644 index f28f35f..0000000 --- a/client/scripts/deploy-to-ipfs.ts +++ /dev/null @@ -1,108 +0,0 @@ -import fs from "fs"; -import path from "path"; -import FormData from "form-data"; -import axios from "axios"; - -// TODO env-ise -const IPFS_API_URL = "http://localhost:5001"; - -interface IPFSAddResponse { - Name: string; - Hash: string; - Size: string; -} - -async function addDirectoryToIPFS(dirPath: string): Promise { - const form = new FormData(); - - function addFilesRecursively(currentPath: string, basePath: string = "") { - const items = fs.readdirSync(currentPath); - - for (const item of items) { - const fullPath = path.join(currentPath, item); - const relativePath = basePath ? path.join(basePath, item) : item; - const stat = fs.statSync(fullPath); - - if (stat.isDirectory()) { - addFilesRecursively(fullPath, relativePath); - } else { - const fileStream = fs.createReadStream(fullPath); - form.append("file", fileStream, { - filepath: relativePath, - }); - } - } - } - - console.log(`📁 Reading files from: ${dirPath}`); - addFilesRecursively(dirPath); - - console.log("☁️ Uploading to IPFS..."); - - try { - const response = await axios.post( - `${IPFS_API_URL}/api/v0/add?recursive=true&wrap-with-directory=true`, - form, - { - headers: { - ...form.getHeaders(), - }, - maxBodyLength: Infinity, - maxContentLength: Infinity, - }, - ); - - // The response is newline-delimited JSON, get the last line which is the directory - const lines = response.data - .toString() - .trim() - .split("\n") - .filter((line) => line.trim()); - const lastLine = lines[lines.length - 1]; - const result = JSON.parse(lastLine) as IPFSAddResponse; - - return result.Hash; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("IPFS API Error:", error.message); - if (error.response) { - console.error("Response:", error.response.data); - } - } - throw error; - } -} - -async function main() { - try { - console.log("🚀 Starting client deployment to IPFS..."); - - const distDir = path.join(process.cwd(), "dist"); - - if (!fs.existsSync(distDir)) { - throw new Error( - `Build directory ${distDir} does not exist. Run 'bun run build' first.`, - ); - } - - const hash = await addDirectoryToIPFS(distDir); - - console.log("✅ Upload successful!"); - console.log(`📍 IPFS Hash: ${hash}`); - console.log(`🌐 Local Gateway URL: http://localhost:6969/ipfs/${hash}`); - console.log(`🌐 Public Gateway URL: https://ipfs.io/ipfs/${hash}`); - - return hash; - } catch (error) { - console.error("❌ Deployment failed:", error); - throw error; - } -} - -main() - .then(() => { - process.exit(0); - }) - .catch(() => { - process.exit(1); - }); diff --git a/client/src/App.tsx b/client/src/App.tsx index bac122f..08be69f 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,29 +1,31 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { AppLayout } from "@/_components/layout"; +import { InAppBrowserWarning } from "@/_components/status/in-app-browser-warning"; +import { AboutPage } from "@/pages/about"; +import AccountPage from "@/pages/account"; +import AccountsPage from "@/pages/accounts"; +import ContactsPage from "@/pages/contacts"; +import DecryptPage from "@/pages/decrypt"; +import EncryptPage from "@/pages/encrypt"; +import { HomePage } from "@/pages/home"; +import NotFoundPage from "@/pages/not-found"; +import SendPage from "@/pages/send"; +import { SettingsPage } from "@/pages/settings"; +import SharePage from "@/pages/share"; +import StatusPage from "@/pages/status"; +import TestingPage from "@/pages/testing"; +import TransactionsPage from "@/pages/transactions"; import { HashRouter, Route, Routes } from "react-router-dom"; +import { AuthProvider } from "./_providers/auth-provider"; +import { ProtectedRoute } from "./_providers/protected-route"; +import { QueryClientProvider } from "./_providers/query-client"; +import { ThemeProvider } from "./_providers/theme-provider"; import "./App.css"; -import { InAppBrowserWarning } from "./components/in-app-browser-warning"; -import { AppLayout } from "./components/layout"; -import { ProtectedRoute } from "./components/protected-route"; -import { ThemeProvider } from "./components/theme-provider"; -import { AuthProvider } from "./lib/auth-context"; -import { AboutPage } from "./pages/about"; -import AccountPage from "./pages/account"; -import ContactsPage from "./pages/contacts"; -import { HomePage } from "./pages/home"; -import NotFoundPage from "./pages/not-found"; -import { SettingsPage } from "./pages/settings"; -import SharePage from "./pages/share"; -import StatusPage from "./pages/status"; -import TestingPage from "./pages/testing"; -import TransactionsPage from "./pages/transactions"; - -const queryClient = new QueryClient(); function App() { return ( - + @@ -37,6 +39,14 @@ function App() { } /> + + + + } + /> } /> + + + + } + /> + + + + } + /> + + + + } + /> } /> } /> } /> diff --git a/client/src/_components/PUM/decrypt.tsx b/client/src/_components/PUM/decrypt.tsx new file mode 100644 index 0000000..fcadff1 --- /dev/null +++ b/client/src/_components/PUM/decrypt.tsx @@ -0,0 +1,62 @@ +import type { SupportedAsset } from "shared/constants/token"; +import StepIndicator, { type EncryptionStep } from "./step"; + +export const Decrypt = ({ + asset, + formattedBalance, + formattedPrivateBalance, + decryptAmountNum, + decryptionStep, + error, +}: { + asset: SupportedAsset; + formattedBalance: number; + formattedPrivateBalance: number; + decryptAmountNum: number; + decryptionStep: EncryptionStep; + error: Error | null; +}) => { + return ( +
+
+ {/* Left column - Transaction summary */} +
+

+ Once this transaction is complete: +

+

+ Public:{" "} + {(formattedBalance + decryptAmountNum).toFixed(asset.roundTo ?? 2)}{" "} + {asset.symbol} +

+

+ Private:{" "} + {(formattedPrivateBalance - decryptAmountNum).toFixed( + asset.roundTo ?? 2, + )}{" "} + {asset.symbol} +

+
+ + {/* Vertical divider */} +
+ + {/* Right column - Steps */} +
+ + +
+
+
+ ); +}; diff --git a/client/src/_components/PUM/encrpyt.tsx b/client/src/_components/PUM/encrpyt.tsx new file mode 100644 index 0000000..f73e249 --- /dev/null +++ b/client/src/_components/PUM/encrpyt.tsx @@ -0,0 +1,64 @@ +import type { SupportedAsset } from "shared/constants/token"; +import StepIndicator, { type EncryptionStep } from "./step"; + +export const Encrypt = ({ + asset, + formattedBalance, + formattedPrivateBalance, + amount, + encryptionStep, + error, +}: { + asset: SupportedAsset; + formattedBalance: number; + formattedPrivateBalance: number; + amount: number; + encryptionStep: EncryptionStep; + error: Error | null; +}) => { + return ( +
+
+ {/* Left column - Transaction summary */} +
+

+ Once this transaction is complete: +

+

+ Public: {(formattedBalance - amount).toFixed(asset.roundTo ?? 2)}{" "} + {asset.symbol} +

+ +

+ Private: {formattedPrivateBalance + amount} {asset.symbol} +

+
+ + {/* Vertical divider */} +
+ + {/* Right column - Steps */} +
+ + + +
+
+
+ ); +}; diff --git a/client/src/_components/PUM/inline-encrypt-confirmation.tsx b/client/src/_components/PUM/inline-encrypt-confirmation.tsx new file mode 100644 index 0000000..1e12730 --- /dev/null +++ b/client/src/_components/PUM/inline-encrypt-confirmation.tsx @@ -0,0 +1,357 @@ +import { Alert, AlertDescription } from "@/_components/ui/alert"; +import { Button } from "@/_components/ui/button"; +import { Input } from "@/_components/ui/input"; +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@/_components/ui/tabs"; +import { useCanEncrypt } from "@/_hooks/use-can-encrypt"; +import { useEncryptMutation } from "@/_hooks/use-encrypt"; +import { useERC20Balance } from "@/_hooks/use-erc20-balance"; +import { usePrivateBalance } from "@/_hooks/use-private-balance"; +import { useUserAssetNotes } from "@/_hooks/use-user-asset-notes"; +import { ethers } from "ethers"; +import { AlertCircle } from "lucide-react"; +import { useState } from "react"; +import type { SupportedAsset } from "shared/constants/token"; +import { Decrypt } from "./decrypt"; +import { Encrypt } from "./encrpyt"; +import type { EncryptionStep } from "./step"; + +interface InlineEncryptConfirmationProps { + asset: SupportedAsset; + onCancel: () => void; + onSuccess: () => void; +} + +export function InlineEncryptConfirmation({ + asset, + onCancel, + // onSuccess, +}: InlineEncryptConfirmationProps) { + const [activeTab, setActiveTab] = useState<"encrypt" | "decrypt">("encrypt"); + const [amount, setAmount] = useState(""); + const [decryptAmount, setDecryptAmount] = useState(""); + + const [encryptionStep, setEncryptionStep] = useState(); + const [decryptionStep, setDecryptionStep] = useState(); + const { refetch: retchUserAssetNotes } = useUserAssetNotes(asset.address); + const { canEncrypt, isLoading: isLoadingCanEncrypt } = useCanEncrypt(); + + const onTxSuccess = () => { + retchUserAssetNotes(); + setEncryptionStep("complete"); + }; + + const { + mutate: encrypt, + isPending, + error, + } = useEncryptMutation({ + onApprovalSuccess: () => setEncryptionStep("proof-generation"), + onZkProofSuccess: () => setEncryptionStep("deposit"), + onTxReceiptSuccess: () => onTxSuccess(), + // onTxSuccess: TODO readd + }); + + // public balance data + const { data: balanceData } = useERC20Balance(asset); + const formattedBalance = balanceData + ? parseFloat(ethers.formatUnits(balanceData, asset.decimals)) + : 0; + + // private balance data + const { assetTotal: privateBalance } = usePrivateBalance(asset); + const formattedPrivateBalance = privateBalance + ? parseFloat(ethers.formatUnits(privateBalance, asset.decimals)) + : 0; + + const amountNum = parseFloat(amount) || 0; + const hasError = amountNum > formattedBalance || amountNum <= 0; + const errorMessage = + amountNum <= 0 + ? "Amount must be greater than 0" + : amountNum > formattedBalance + ? `Insufficient balance. You have ${formattedBalance} ${asset.symbol}` + : ""; + + const handleNext = () => { + setEncryptionStep("review"); + }; + + const handleConfirm = async () => { + if (hasError) return; + setEncryptionStep("approval"); + + encrypt( + { + assetId: asset.address, + chainId: asset.chainId, + amount: amountNum, + decimals: asset.decimals, + }, + { + onSuccess: () => { + // onSuccess(); + }, + onError: (e) => { + console.error(e); + setEncryptionStep(undefined); + }, + }, + ); + }; + + // TODO: Implement decrypt mutation hook + const handleDecrypt = async () => { + if (decryptHasError) return; + setDecryptionStep("review"); + + // TODO: Implement actual decrypt logic + console.log("Decrypt functionality to be implemented", { + assetId: asset.address, + chainId: asset.chainId, + amount: decryptAmountNum, + decimals: asset.decimals, + }); + }; + + const handleDecryptConfirm = async () => { + if (decryptHasError) return; + setDecryptionStep("approval"); + + // TODO: Call decrypt mutation when implemented + console.log("Decrypt confirm - to be implemented"); + }; + + const decryptAmountNum = parseFloat(decryptAmount) || 0; + const decryptHasError = + decryptAmountNum > (privateBalance ?? 0n) || decryptAmountNum <= 0; + const decryptErrorMessage = + decryptAmountNum <= 0 + ? "Amount must be greater than 0" + : decryptAmountNum > (privateBalance ?? 0n) + ? `Insufficient private balance. You have ${privateBalance} ${asset.symbol}` + : ""; + + return ( +
+ setActiveTab(v as "encrypt" | "decrypt")} + > + + + Encrypt + + + Decrypt + + + + + {!encryptionStep && ( +
+
+

Encrypt {asset.symbol}

+
+ +
+ + setAmount(e.target.value)} + className="text-sm" + disabled={isPending} + aria-invalid={amount !== "" && hasError} + /> + {amount !== "" && hasError && ( +

{errorMessage}

+ )} +

+ Public Balance: {formattedBalance.toFixed(asset.roundTo)}{" "} + {asset.symbol} +

+
+
+ )} + + {encryptionStep !== undefined && + amount !== "" && + !hasError && + amountNum > 0 && ( + + )} + + {/* Authorization Alert */} + {!canEncrypt && !isLoadingCanEncrypt && ( + + + + You are currently not authorised to encrypt funds. + + + )} + +
+ + {!encryptionStep && ( + + )} + {encryptionStep && ( + + )} +
+ + {error && ( +
+ Error: {error.message} +
+ )} + + {/* TODO make this prettier */} + {encryptionStep === "complete" && ( +
+ Funds encrypted! You can view all encrypted funds in your + transaction history. +
+ )} +
+ + + {!decryptionStep && ( +
+
+

Decrypt {asset.symbol}

+
+ +
+ + setDecryptAmount(e.target.value)} + className="text-sm" + aria-invalid={decryptAmount !== "" && decryptHasError} + /> + {decryptAmount !== "" && decryptHasError && ( +

+ {decryptErrorMessage} +

+ )} +

+ Private Balance:{" "} + {formattedPrivateBalance.toFixed(asset.roundTo)}{" "} + {asset.symbol} +

+
+
+ )} + + {decryptionStep !== undefined && + decryptAmount !== "" && + !decryptHasError && + decryptAmountNum > 0 && ( + + )} + +
+ + {!decryptionStep && ( + + )} + {decryptionStep && ( + + )} +
+ + {/* TODO make this prettier */} + {decryptionStep === "complete" && ( +
+ Funds decrypted! You can view your updated balance on the account + page. +
+ )} +
+
+
+ ); +} diff --git a/client/src/_components/PUM/step.tsx b/client/src/_components/PUM/step.tsx new file mode 100644 index 0000000..7ae3eb6 --- /dev/null +++ b/client/src/_components/PUM/step.tsx @@ -0,0 +1,41 @@ +import { X, Check, Loader2 } from "lucide-react"; + +export type EncryptionStep = + | "review" + | "approval" + | "proof-generation" + | "deposit" + | "complete"; + +const StepIndicator = ({ + label, + step, + currentStep, + error: stepError, +}: { + label: string; + step: EncryptionStep; + currentStep?: EncryptionStep; + error?: Error | null; +}) => { + const isComplete = step === "complete"; + const isCurrent = currentStep === step && !isComplete; + const hasError = stepError && isCurrent; + + return ( +
+ + {hasError ? ( + + ) : isComplete ? ( + + ) : isCurrent ? ( + + ) : null} + + {label} +
+ ); +}; + +export default StepIndicator; diff --git a/client/src/_components/account/account-navigation.tsx b/client/src/_components/account/account-navigation.tsx new file mode 100644 index 0000000..6b67ee4 --- /dev/null +++ b/client/src/_components/account/account-navigation.tsx @@ -0,0 +1,78 @@ +import { Button } from "@/_components/ui/button"; +import { + ArrowUpRight, + LockKeyhole, + LockKeyholeOpen, + Share2, + Users, +} from "lucide-react"; +import { useState } from "react"; +import { Link } from "react-router-dom"; +import { ShareProfile } from "./share-profile"; + +export const AccountNavigation = () => { + const [isShareDialogOpen, setIsShareDialogOpen] = useState(false); + return ( +
+ setIsShareDialogOpen(!isShareDialogOpen)} + /> + {/* Top row: contacts and share */} +
+ + +
+ + {/* Bottom row: send, encrypt, decrypt */} +
+ + + +
+
+ ); +}; diff --git a/client/src/_components/account/address-card.tsx b/client/src/_components/account/address-card.tsx new file mode 100644 index 0000000..f917a59 --- /dev/null +++ b/client/src/_components/account/address-card.tsx @@ -0,0 +1,109 @@ +import { Button } from "@/_components/ui/button"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/_components/ui/card"; +import { copyToClipboard } from "@/lib/utils"; +import { Check, Copy } from "lucide-react"; +import { useState } from "react"; +import { toast } from "sonner"; + +interface AddressCardProps { + publicAddress: string | null; + privateAddress: string | null; + signingKey: string | null; +} + +export function AddressCard({ + publicAddress, + privateAddress, + signingKey, +}: AddressCardProps) { + const [copiedPublic, setCopiedPublic] = useState(false); + const [copiedPrivate, setCopiedPrivate] = useState(false); + const [copiedSigning, setCopiedSigning] = useState(false); + + const handleCopy = async ( + text: string, + type: "EVM" | "Private" | "Signing", + ) => { + if (!text) return; + + const success = await copyToClipboard(text); + if (success) { + if (type === "EVM") { + setCopiedPublic(true); + setTimeout(() => setCopiedPublic(false), 2000); + } else if (type === "Private") { + setCopiedPrivate(true); + setTimeout(() => setCopiedPrivate(false), 2000); + } else { + setCopiedSigning(true); + setTimeout(() => setCopiedSigning(false), 2000); + } + toast.success("Address copied to clipboard"); + } else { + toast.error("Failed to copy address"); + } + }; + + const Address = ({ + address, + type, + }: { + address: string | null; + type: "Private" | "Signing" | "EVM"; + }) => { + if (!address) return null; + + const isCopied = + (type === "EVM" && copiedPublic) || + (type === "Private" && copiedPrivate) || + (type === "Signing" && copiedSigning); + + const label = + type === "EVM" + ? "Ethereum Address" + : type === "Private" + ? "Poseidon" + : "Signing Key"; + + return ( +
+
+
+

{label}

+

{address}

+
+ +
+
+ ); + }; + + return ( + + + My Addresses + + +
+
+
+ + + ); +} diff --git a/client/src/_components/account/asset-breakdown.stories.tsx b/client/src/_components/account/asset-breakdown.stories.tsx new file mode 100644 index 0000000..041e9e7 --- /dev/null +++ b/client/src/_components/account/asset-breakdown.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; + +import { AssetBreakdown } from "./asset-breakdown"; + +const meta = { + component: AssetBreakdown, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/client/src/_components/account/asset-breakdown.tsx b/client/src/_components/account/asset-breakdown.tsx new file mode 100644 index 0000000..e47a5e0 --- /dev/null +++ b/client/src/_components/account/asset-breakdown.tsx @@ -0,0 +1,142 @@ +import { InlineEncryptConfirmation } from "@/_components/PUM/inline-encrypt-confirmation"; +import { Button } from "@/_components/ui/button"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/_components/ui/card"; +import { Separator } from "@/_components/ui/separator"; +import { ArrowRight, ArrowRightLeft } from "lucide-react"; +import { Fragment, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { DEFAULT_ASSETS, type SupportedAsset } from "shared/constants/token"; +import { BalanceRow, PrivateBalanceRow, TotalBalanceRow } from "./balance"; + +export function AssetBreakdown({ isPortfolio }: { isPortfolio?: boolean }) { + const navigate = useNavigate(); + + const [selectedAsset, setSelectedAsset] = useState( + null, + ); + + const handleEncryptClick = (asset: SupportedAsset) => { + if (selectedAsset) { + setSelectedAsset(asset === selectedAsset ? null : asset); + } else { + setSelectedAsset(asset); + } + }; + const handleCancelEncrypt = () => { + setSelectedAsset(null); + }; + + const handleEncryptSuccess = () => { + setSelectedAsset(null); + }; + + return ( + + +
+ Accounts + {!isPortfolio && ( + + )} +
+
+ +
+ + + {DEFAULT_ASSETS.map((asset, i) => ( + + + + + + + + {selectedAsset && selectedAsset.symbol === asset.symbol && ( + + + + )} + + ))} + +
+
+ + {asset.symbol} +
+
+
+
+ +
+ + + + +
+
+ + Public: + + +
+ +
+ + Private: + + +
+
+ + +
+
+ +
+
+
+
+ ); +} diff --git a/client/src/_components/account/balance-card.stories.tsx b/client/src/_components/account/balance-card.stories.tsx new file mode 100644 index 0000000..3a0fac9 --- /dev/null +++ b/client/src/_components/account/balance-card.stories.tsx @@ -0,0 +1,15 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; + +import { BalanceCard } from "./balance-card"; + +const meta = { + component: BalanceCard, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; diff --git a/client/src/_components/account/balance-card.tsx b/client/src/_components/account/balance-card.tsx new file mode 100644 index 0000000..73fb57d --- /dev/null +++ b/client/src/_components/account/balance-card.tsx @@ -0,0 +1,137 @@ +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/_components/ui/card"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, +} from "@/_components/ui/select"; +import { Skeleton } from "@/_components/ui/skeleton"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/_components/ui/tooltip"; +import { useAccountTotal } from "@/_hooks/use-account-total"; +import { useAudUsdPrice, useEthUsdPrice } from "@/_hooks/use-chainlink-price"; +import { + usePreferredCurrency, + type Currency, +} from "@/_hooks/use-preferred-currency"; +import { formatDollarAmount } from "@/lib/formatting/data-formatting"; +import { BadgeDollarSign } from "lucide-react"; +import { SyncState } from "./sync-state"; + +export const BalanceCard = () => { + // Fetch price data from Chainlink + const { data: ethUsdPrice, isLoading: isLoadingEthUsd } = useEthUsdPrice(); + const { data: audUsdPrice, isLoading: isLoadingAudUsd } = useAudUsdPrice(); + + const { + currency, + setCurrency, + isLoading: isLoadingCurrency, + } = usePreferredCurrency(); + + const { totalUsd, isLoading: isLoadingTotal } = useAccountTotal(); + + // Calculate total in AUD + const totalAud = + audUsdPrice && totalUsd + ? totalUsd / parseFloat(audUsdPrice.formattedPrice) + : 0; + + // Calculate ETH value in AUD (ETH/USD / AUD/USD) + const ethAudValue = + ethUsdPrice && audUsdPrice + ? formatDollarAmount( + parseFloat(ethUsdPrice.formattedPrice) / + parseFloat(audUsdPrice.formattedPrice), + ) + : null; + + const ethUsdValue = ethUsdPrice + ? formatDollarAmount(parseFloat(ethUsdPrice.formattedPrice)) + : null; + + const isPriceLoading = isLoadingEthUsd || isLoadingAudUsd; + + return ( + + +
+ {/* Total Value */} +
+ {isLoadingTotal || isLoadingCurrency ? ( + + ) : ( +
+ + {currency === "AUD" + ? `$${formatDollarAmount(totalAud)}` + : `$${formatDollarAmount(totalUsd)}`} + + + {currency} + + +
+ )} +
+
+ {/* TODO readd */} +
+ +
+
+ +
+ {isPriceLoading ? ( + + ) : ethAudValue && ethUsdValue ? ( + <> + + 1 ETH = {ethAudValue} AUD / {ethUsdValue} USD + + {/* Desktop: tooltip on hover */} + + + + Chainlink + + + +

Pricing data provided by Chainlink pricing feeds

+
+
+ {/* Mobile: inline text */} + + Chainlink + prices provided by Chainlink + + + ) : null} +
+
+
+ ); +}; diff --git a/client/src/components/token/balance.tsx b/client/src/_components/account/balance.tsx similarity index 52% rename from client/src/components/token/balance.tsx rename to client/src/_components/account/balance.tsx index 4887abc..96d3298 100644 --- a/client/src/components/token/balance.tsx +++ b/client/src/_components/account/balance.tsx @@ -1,6 +1,6 @@ -import { Skeleton } from "@/components/ui/skeleton"; -import { useERC20Balance } from "@/hooks/use-erc20-balance"; -import { useUserAssetNotes } from "@/hooks/use-user-asset-notes"; +import { Skeleton } from "@/_components/ui/skeleton"; +import { useERC20Balance } from "@/_hooks/use-erc20-balance"; +import { usePrivateBalance } from "@/_hooks/use-private-balance"; import { ethers, formatUnits } from "ethers"; import type { SupportedAsset } from "shared/constants/token"; @@ -15,7 +15,7 @@ export const BalanceRow = ({ const formatBalance = (balance: bigint) => { const formatted = ethers.formatUnits(balance, asset.decimals); - if (asset.roundTo !== undefined) { + if (asset.roundTo !== undefined && balance != 0n) { return parseFloat(formatted).toFixed(asset.roundTo); } return formatted; @@ -23,11 +23,11 @@ export const BalanceRow = ({ return (
- {isLoading && } - {data && !isLoading && ( + {isLoading && } + {!isLoading && (
-
- {formatBalance(data)} +
+ {formatBalance(data ?? 0n)} {description && {description}}
@@ -43,20 +43,14 @@ export const PrivateBalanceRow = ({ asset: SupportedAsset; description?: string; }) => { - const { data: assetNotes, isLoading } = useUserAssetNotes(asset.address); - - const assetTotal = assetNotes - ? assetNotes.reduce((acc, curr) => { - return acc + BigInt(curr.assetAmount); - }, 0n) - : undefined; + const { assetNotes, isLoading, assetTotal } = usePrivateBalance(asset); return (
- {isLoading && } + {isLoading && } {assetNotes && !isLoading && (
-
+
{assetTotal && formatUnits(assetTotal, asset.decimals)} {description && {description}}
@@ -67,15 +61,14 @@ export const PrivateBalanceRow = ({ }; export const TotalBalanceRow = ({ asset }: { asset: SupportedAsset }) => { - const { data: assetNotes, isLoading } = useUserAssetNotes(asset.address); - - const assetTotal = assetNotes - ? assetNotes.reduce((acc, curr) => { - return acc + BigInt(curr.assetAmount); - }, 0n) - : undefined; + const { + assetNotes, + isLoading: isLoadingPrivate, + assetTotal: privateAssetTotal, + } = usePrivateBalance(asset); - const { data } = useERC20Balance(asset); + const { data: erc20BalanceData, isLoading: isLoadingPublic } = + useERC20Balance(asset); const sumAndFormatBalances = ( publicBalance: bigint, @@ -93,14 +86,24 @@ export const TotalBalanceRow = ({ asset }: { asset: SupportedAsset }) => { return (
- {isLoading && } - {assetNotes && !isLoading && ( -
-
- {assetTotal && data && sumAndFormatBalances(data, assetTotal)} -
-
+ {(isLoadingPrivate || isLoadingPublic) && ( + )} + + {assetNotes && + !(isLoadingPrivate || isLoadingPublic) && + privateAssetTotal !== undefined && ( +
+
+ {erc20BalanceData !== undefined && ( + <> + {sumAndFormatBalances(erc20BalanceData, privateAssetTotal)}{" "} + {asset.symbol} + + )} +
+
+ )}
); }; diff --git a/client/src/_components/account/portfolio-chart.tsx b/client/src/_components/account/portfolio-chart.tsx new file mode 100644 index 0000000..2f27f88 --- /dev/null +++ b/client/src/_components/account/portfolio-chart.tsx @@ -0,0 +1,289 @@ +import * as React from "react"; +import { Label, Pie, PieChart } from "recharts"; +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + type ChartConfig, +} from "@/_components/ui/chart"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/_components/ui/tooltip"; +import { useAccountTotal } from "@/_hooks/use-account-total"; +import { usePreferredCurrency } from "@/_hooks/use-preferred-currency"; +import { useAudUsdPrice, useEthUsdPrice } from "@/_hooks/use-chainlink-price"; +import { useERC20Balances } from "@/_hooks/use-erc20-balance"; +import { DEFAULT_ASSETS } from "shared/constants/token"; +import { ethers } from "ethers"; +import { Skeleton } from "@/_components/ui/skeleton"; +import { formatCompactCurrency } from "@/lib/formatting/currency-formatting"; + +const chartConfig = { + value: { + label: "Value", + }, + USDC: { + label: "USDC", + color: "var(--chart-1)", + }, + AUDD: { + label: "AUDD", + color: "var(--chart-2)", + }, + ETH: { + label: "ETH", + color: "var(--chart-3)", + }, +} satisfies ChartConfig; + +export function PortfolioChart() { + const { totalUsd, isLoading: isLoadingTotal } = useAccountTotal(); + const { currency } = usePreferredCurrency(); + const { data: ethUsdPrice } = useEthUsdPrice(); + const { data: audUsdPrice } = useAudUsdPrice(); + const { data: assetBalances, isLoading: isLoadingAssets } = + useERC20Balances(DEFAULT_ASSETS); + + // Calculate asset values in USD for the chart + const chartData = React.useMemo(() => { + if (!ethUsdPrice || !audUsdPrice || !assetBalances) return []; + + return assetBalances + .map((asset) => { + if (!asset.balance) return null; + + const balanceFormatted = parseFloat( + ethers.formatUnits(asset.balance, asset.decimals), + ); + + let valueUsd = 0; + + if (asset.symbol === "ETH") { + valueUsd = balanceFormatted * parseFloat(ethUsdPrice.formattedPrice); + } else if (asset.symbol === "AUDD") { + valueUsd = balanceFormatted * parseFloat(audUsdPrice.formattedPrice); + } else if (asset.symbol === "USDC") { + valueUsd = balanceFormatted; + } + + return { + asset: asset.symbol, + value: valueUsd, + fill: `var(--color-${asset.symbol})`, + }; + }) + .filter(Boolean); + }, [ethUsdPrice, audUsdPrice, assetBalances]); + + // Calculate total in preferred currency + const totalAud = + audUsdPrice && totalUsd + ? totalUsd / parseFloat(audUsdPrice.formattedPrice) + : 0; + + const displayTotal = currency === "AUD" ? totalAud : totalUsd; + const { formatted, full } = formatCompactCurrency(displayTotal); + + return ( + + {isLoadingTotal || isLoadingAssets ? ( +
+ +
+ ) : ( + + } + /> + + + + )} +
+ ); +} + +const legendColors: Record = { + USDC: "var(--chart-1)", + AUDD: "var(--chart-2)", + ETH: "var(--chart-3)", +}; + +function PortfolioLegend() { + const { currency } = usePreferredCurrency(); + const { data: ethUsdPrice } = useEthUsdPrice(); + const { data: audUsdPrice } = useAudUsdPrice(); + const { data: assetBalances, isLoading } = useERC20Balances(DEFAULT_ASSETS); + + const legendData = React.useMemo(() => { + if (!ethUsdPrice || !audUsdPrice || !assetBalances) return []; + + return assetBalances + .map((asset) => { + if (!asset.balance) return null; + + const balanceFormatted = parseFloat( + ethers.formatUnits(asset.balance, asset.decimals), + ); + + let valueUsd = 0; + + if (asset.symbol === "ETH") { + valueUsd = balanceFormatted * parseFloat(ethUsdPrice.formattedPrice); + } else if (asset.symbol === "AUDD") { + valueUsd = balanceFormatted * parseFloat(audUsdPrice.formattedPrice); + } else if (asset.symbol === "USDC") { + valueUsd = balanceFormatted; + } + + // Convert to preferred currency + const displayValue = + currency === "AUD" + ? valueUsd / parseFloat(audUsdPrice.formattedPrice) + : valueUsd; + + return { + symbol: asset.symbol, + value: displayValue, + color: legendColors[asset.symbol] || "var(--chart-1)", + }; + }) + .filter(Boolean) + .sort((a, b) => (b?.value ?? 0) - (a?.value ?? 0)); + }, [ethUsdPrice, audUsdPrice, assetBalances, currency]); + + if (isLoading) { + return ( +
+ {[1, 2, 3].map((i) => ( + + ))} +
+ ); + } + + const currencySymbol = currency === "AUD" ? "A$" : "$"; + + return ( +
+ {legendData.map((item) => ( +
+
+ {item?.symbol} + + {currencySymbol} + {item?.value?.toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + +
+ ))} +
+ ); +} + +export function PortfolioChartWithTooltip() { + const { totalUsd, isLoading: isLoadingTotal } = useAccountTotal(); + const { currency } = usePreferredCurrency(); + const { data: audUsdPrice } = useAudUsdPrice(); + + const totalAud = + audUsdPrice && totalUsd + ? totalUsd / parseFloat(audUsdPrice.formattedPrice) + : 0; + + const displayTotal = currency === "AUD" ? totalAud : totalUsd; + const { formatted, full } = formatCompactCurrency(displayTotal); + + // If the value is large enough to be compacted, show tooltip + if (formatted !== full && !isLoadingTotal) { + return ( +
+ + +
+ +
+
+ +

{full}

+
+
+ +
+ ); + } + + return ( +
+ + +
+ ); +} diff --git a/client/src/_components/account/share-profile.tsx b/client/src/_components/account/share-profile.tsx new file mode 100644 index 0000000..5adc54f --- /dev/null +++ b/client/src/_components/account/share-profile.tsx @@ -0,0 +1,277 @@ +import { Checkbox } from "@/_components/ui/checkbox"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/_components/ui/dialog"; +import { Input } from "@/_components/ui/input"; +import { Label } from "@/_components/ui/label"; +import { useAuth } from "@/_providers/auth-provider"; +import { addNicknameHash } from "@/lib/formatting/nickname-hash"; +import { AnimatePresence, motion } from "framer-motion"; +import { Check, Copy, Info, QrCode } from "lucide-react"; +import { QRCodeSVG } from "qrcode.react"; +import { useEffect, useMemo, useState } from "react"; +import { toast } from "sonner"; +import { Button } from "../ui/button"; + +const NICKNAME_STORAGE_KEY = "shareProfileNickname"; + +interface AddressFieldProps { + label: string; + value: string | null; +} + +function AddressField({ label, value }: AddressFieldProps) { + const [copied, setCopied] = useState(false); + + const handleCopy = async (e: React.MouseEvent) => { + e.preventDefault(); + if (!value) return; + + try { + await navigator.clipboard.writeText(value); + setCopied(true); + toast.success(`${label} copied!`); + setTimeout(() => setCopied(false), 2000); + } catch (error) { + console.error("Failed to copy:", error); + toast.error("Failed to copy"); + } + }; + + if (!value) return null; + + return ( +
+
+

+ {label}: +

+

+ {value} +

+
+ +
+ ); +} + +export const ShareProfile = ({ + isShareDialogOpen, + setIsShareDialogOpen, +}: { + isShareDialogOpen: boolean; + setIsShareDialogOpen: () => void; +}) => { + const { address, signingKey, privateAddress } = useAuth(); + + const [sharePublic, setSharePublic] = useState(true); + const [sharePrivate, setSharePrivate] = useState(true); + const [showQR, setShowQR] = useState(false); + const [nickname, setNickname] = useState(() => { + if (typeof window === "undefined") return ""; + return localStorage.getItem(NICKNAME_STORAGE_KEY) || ""; + }); + + // Save nickname to localStorage when it changes + useEffect(() => { + if (typeof window === "undefined") return; + if (nickname.trim()) { + localStorage.setItem(NICKNAME_STORAGE_KEY, nickname.trim()); + } + }, [nickname]); + + // Generate the profile URL + const profileUrl = useMemo(() => { + const params = new URLSearchParams(); + + // Add address if sharing public + if (sharePublic && address) { + params.append("address", address); + } + + // Add private addresses if sharing private + if (sharePrivate) { + if (privateAddress) { + params.append("privateAddress", privateAddress); + } + if (signingKey) { + params.append("envelope", signingKey); + } + } + + // Add nickname with hash if provided + if (nickname.trim()) { + const nicknameWithHash = addNicknameHash(nickname.trim()); + params.append("nickname", nicknameWithHash); + } + + const baseUrl = import.meta.env.VITE_DOMAIN || "http://localhost:5173"; + return `${baseUrl}/#/share?${params.toString()}`; + }, [ + sharePublic, + sharePrivate, + address, + privateAddress, + signingKey, + nickname, + ]); + + const handleCopyProfileURL = async () => { + try { + await navigator.clipboard.writeText(profileUrl); + toast.success("Profile URL copied to clipboard!"); + } catch (error) { + console.error("Failed to copy:", error); + toast.error("Failed to copy URL"); + } + }; + + return ( + + e.preventDefault()} + > + + Share your commbank.eth details + +
+
+ + setNickname(e.target.value)} + /> +
+ +

+ Anyone you share your details with will see this name. +

+
+
+
+ + {!showQR ? ( + + + + + + ) : ( + +
+ +
+
+ )} +
+
+ +
+ + +
+ +
+
+
+ ); +}; diff --git a/client/src/components/account/sync-button.tsx b/client/src/_components/account/sync-button.tsx similarity index 58% rename from client/src/components/account/sync-button.tsx rename to client/src/_components/account/sync-button.tsx index ad50ddf..75eee36 100644 --- a/client/src/components/account/sync-button.tsx +++ b/client/src/_components/account/sync-button.tsx @@ -1,18 +1,18 @@ -import { Button } from "@/components/ui/button"; +import { Button } from "@/_components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, -} from "@/components/ui/dialog"; +} from "@/_components/ui/dialog"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, -} from "@/components/ui/tooltip"; -import { CheckCircle, Loader2, XCircle } from "lucide-react"; +} from "@/_components/ui/tooltip"; +import { CheckCircle, Loader2, RefreshCw, XCircle } from "lucide-react"; import { useState } from "react"; type SyncState = "syncing" | "complete" | "error"; @@ -20,11 +20,13 @@ type SyncState = "syncing" | "complete" | "error"; interface SyncButtonProps { state: SyncState; errorMessage?: string; + onSync?: () => void; } export function SyncButton({ state, errorMessage = "An error occurred during sync", + onSync, }: SyncButtonProps) { const [isDialogOpen, setIsDialogOpen] = useState(false); @@ -38,14 +40,8 @@ export function SyncButton({ {state === "syncing" && ( - Scanning for new private balances @@ -56,16 +52,19 @@ export function SyncButton({ - Account Synced + +
+ + Synced - Click to refresh +
+
)} @@ -74,16 +73,14 @@ export function SyncButton({ - Error Syncing + Error Syncing - Click for details @@ -92,6 +89,19 @@ export function SyncButton({ Sync Error {errorMessage} +
+ +
diff --git a/client/src/components/account/sync-state.tsx b/client/src/_components/account/sync-state.tsx similarity index 60% rename from client/src/components/account/sync-state.tsx rename to client/src/_components/account/sync-state.tsx index 8c15bfe..8429b7d 100644 --- a/client/src/components/account/sync-state.tsx +++ b/client/src/_components/account/sync-state.tsx @@ -1,12 +1,7 @@ -import type { Payload, TreeLeaf } from "@/_types"; -import { useIndexerLeafs } from "@/hooks/use-indexer-leafs"; -import { useIndexerNotes } from "@/hooks/use-indexer-notes"; -import { - addPayload, - addTreeLeaf, - getAllPayloads, - getAllTreeLeaves, -} from "@/lib/db"; +import type { TreeLeaf } from "@/_types"; +import { useIndexerLeafs } from "@/_hooks/use-indexer-leafs"; +import { useIndexerNotes } from "@/_hooks/use-indexer-notes"; +import { addTreeLeaf, getAllTreeLeaves } from "@/lib/db"; import { useEffect, useState } from "react"; import { SyncButton } from "./sync-button"; @@ -29,16 +24,10 @@ export const SyncState = () => { } // Get existing data from IndexedDB - const [existingLeafs, existingPayloads] = await Promise.all([ - getAllTreeLeaves(), - getAllPayloads(), - ]); + const [existingLeafs] = await Promise.all([getAllTreeLeaves()]); // Create sets of existing IDs for quick lookup const existingLeafIds = new Set(existingLeafs.map((leaf) => leaf.id)); - const existingPayloadIds = new Set( - existingPayloads.map((payload) => payload.id), - ); // Find new leafs that don't exist in IndexedDB const newLeafs: TreeLeaf[] = []; @@ -54,21 +43,8 @@ export const SyncState = () => { } } - // Find new payloads that don't exist in IndexedDB - const newPayloads: Payload[] = []; - if (indexerNotes) { - for (const indexerNote of indexerNotes) { - if (!existingPayloadIds.has(indexerNote.id)) { - newPayloads.push({ - id: indexerNote.id, - encryptedNote: indexerNote.encryptedNote, - }); - } - } - } - // Log what would be written to IndexedDB - if (newLeafs.length > 0 || newPayloads.length > 0) { + if (newLeafs.length > 0) { console.log("=== SYNC: New data to be written ==="); if (newLeafs.length > 0) { @@ -76,16 +52,7 @@ export const SyncState = () => { console.log(newLeafs); } - if (newPayloads.length > 0) { - console.log(`Found ${newPayloads.length} new payloads:`); - console.log(newPayloads); - } - - // TODO: Uncomment when ready to write to database - await Promise.all([ - ...newLeafs.map((leaf) => addTreeLeaf(leaf)), - ...newPayloads.map((payload) => addPayload(payload)), - ]); + await Promise.all([...newLeafs.map((leaf) => addTreeLeaf(leaf))]); console.log("Wrote to DB"); } else { diff --git a/client/src/_components/account/transaction-accordion-item.tsx b/client/src/_components/account/transaction-accordion-item.tsx new file mode 100644 index 0000000..c47e573 --- /dev/null +++ b/client/src/_components/account/transaction-accordion-item.tsx @@ -0,0 +1,378 @@ +import { + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/_components/ui/accordion"; +import { Badge } from "@/_components/ui/badge"; +import { Button } from "@/_components/ui/button"; +import type { Transaction, TransactionStatus, TransactionType } from "@/_types"; +import { + getAssetAddress, + getAssetAmount, + getTransactionVerb, +} from "@/lib/formatting/transactions"; +import { formatUnits } from "ethers/utils"; +import { + AlertCircle, + ArrowDownLeft, + ArrowUpRight, + CheckCircle, + Clock, + Loader2, + Lock, + Send, + Unlock, +} from "lucide-react"; +import { + defaultNetwork, + defaultNetworkAssetByAddress, +} from "shared/constants/token"; + +interface TransactionAccordionItemProps { + transaction: Transaction; +} + +// Get icon and color for each transaction type +function getTransactionIcon(type: TransactionType) { + switch (type) { + case "Deposit": + return { icon: Lock }; + case "Deposit-Pending": + return { icon: Clock }; + case "Withdraw": + return { icon: Unlock }; + case "Transfer": + return { icon: Send }; + case "PrivateTransfer": + return { icon: ArrowUpRight }; + case "Approval": + return { icon: CheckCircle }; + default: + return { icon: ArrowDownLeft }; + } +} + +// Get badge variant based on transaction type +function getBadgeVariant( + type: TransactionType, +): "default" | "secondary" | "outline" | "destructive" { + switch (type) { + case "Deposit": + case "Deposit-Pending": + return "default"; + case "Withdraw": + return "default"; + case "Transfer": + case "PrivateTransfer": + return "default"; + case "Approval": + return "default"; + default: + return "default"; + } +} + +// Get status badge element +function getStatusBadge(status: TransactionStatus | undefined) { + switch (status) { + case "pending": + return ( + + + Pending + + ); + case "confirmed": + return ( + + + Confirmed + + ); + case "failed": + return ( + + + Failed + + ); + case "replaced": + return ( + + + Replaced + + ); + default: + // Backward compatibility: no status means confirmed (old transactions) + return null; + } +} + +// Get recipient display string +function getRecipientDisplay(tx: Transaction): string | null { + if (!tx.recipient) return null; + + if (tx.recipient.nickname) { + return tx.recipient.nickname; + } + + if (tx.recipient.evmAddress) { + return `${tx.recipient.evmAddress.slice(0, 6)}...${tx.recipient.evmAddress.slice(-4)}`; + } + + if (tx.recipient.privateAddress) { + return `${tx.recipient.privateAddress.slice(0, 10)}...`; + } + + return null; +} + +export const TransactionAccordionItem = ({ + transaction: tx, +}: TransactionAccordionItemProps) => { + // Use enhanced asset details if available, otherwise fall back to legacy parsing + const hasEnhancedAsset = tx.asset && tx.asset.symbol; + const legacyAsset = defaultNetworkAssetByAddress[getAssetAddress(tx)]; + + const assetSymbol = hasEnhancedAsset + ? tx.asset!.symbol + : (legacyAsset?.symbol ?? "ETH"); + + const assetDecimals = hasEnhancedAsset + ? tx.asset!.decimals + : (legacyAsset?.decimals ?? 18); + + // Get amount to display + const displayAmount = hasEnhancedAsset + ? tx.asset!.formattedAmount + : tx.value + ? (parseFloat(tx.value) / 1e18).toFixed(4) + : legacyAsset + ? formatUnits(getAssetAmount(tx), legacyAsset.decimals) + : null; + + const etherscanUrl = tx.transactionHash + ? `https://${defaultNetwork !== 1 ? "sepolia.arbiscan.io" : "etherscan.io"}/tx/${tx.transactionHash}` + : null; + + const hasEthValue = tx.value && Number(tx.value) > 0; + const hasAssetValue = + (tx.type === "Deposit" || tx.type === "Deposit-Pending") && + !tx.value && + legacyAsset; + + const { icon: Icon } = getTransactionIcon(tx.type); + const badgeVariant = getBadgeVariant(tx.type); + const recipientDisplay = getRecipientDisplay(tx); + + // Render type-specific details in expanded view + const renderTypeSpecificDetails = () => { + // Show enhanced details if available + if (hasEnhancedAsset) { + return ( + <> +
+

Amount

+

+ {tx.asset!.formattedAmount} {tx.asset!.symbol} +

+
+ + {tx.type === "Transfer" && recipientDisplay && ( +
+

Recipient

+

{recipientDisplay}

+
+ )} + + {tx.type === "Withdraw" && tx.recipient?.evmAddress && ( +
+

Withdrawn To

+

+ {tx.recipient.evmAddress} +

+
+ )} + + ); + } + + // Legacy details rendering + switch (tx.type) { + case "Deposit": + case "Deposit-Pending": + return ( + <> + {hasAssetValue && ( +
+

+ Amount Encrypted +

+

+ {formatUnits(getAssetAmount(tx), assetDecimals)} {assetSymbol} +

+
+ )} + + ); + + case "Withdraw": + return ( + <> + {hasEthValue && ( +
+

+ Amount Withdrawn +

+

+ {(parseFloat(tx.value!) / 1e18).toFixed(6)} ETH +

+
+ )} + + ); + + case "Transfer": + case "PrivateTransfer": + return ( + <> + {hasAssetValue && ( +
+

+ Amount Transferred +

+

+ {formatUnits(getAssetAmount(tx), assetDecimals)} {assetSymbol} +

+
+ )} + + ); + + case "Approval": + return
; + + default: + return null; + } + }; + + return ( + + +
+
+ + {getTransactionVerb(tx.type)} + {assetSymbol} + {tx.status === "pending" && ( + + )} +
+
+ {displayAmount && ( + + {displayAmount} {assetSymbol} + + )} + {/* Legacy display for old transactions without enhanced asset */} + {!displayAmount && hasEthValue && ( + + {(parseFloat(tx.value!) / 1e18).toFixed(4)} ETH + + )} + {!displayAmount && hasAssetValue && ( + + {formatUnits(getAssetAmount(tx), assetDecimals)} {assetSymbol} + + )} +
+
+
+ +
+ {/* Status badge */} + {tx.status && ( +
+ {getStatusBadge(tx.status)} +
+ )} + + {/* Transaction hash (may be missing for pending transactions) */} +
+

+ Transaction Hash +

+ {tx.transactionHash ? ( +

+ {tx.transactionHash} +

+ ) : ( +

+ Awaiting submission... +

+ )} +
+ + {/* Timestamps */} +
+

Date & Time

+

+ {new Date(tx.createdAt || tx.timestamp).toLocaleString()} +

+
+ + {tx.confirmedAt && tx.confirmedAt !== tx.createdAt && ( +
+

Confirmed At

+

+ {new Date(tx.confirmedAt).toLocaleString()} +

+
+ )} + + {/* Type-specific details */} + {renderTypeSpecificDetails()} + + {/* Error message for failed transactions */} + {tx.status === "failed" && tx.errorMessage && ( +
+

Error

+

{tx.errorMessage}

+
+ )} + + {/* Gas used (for confirmed transactions) */} + {tx.gasUsed && ( +
+

Gas Used

+

{tx.gasUsed}

+
+ )} + + {/* Etherscan link (only if we have a hash) */} + {etherscanUrl && ( + + )} +
+
+
+ ); +}; diff --git a/client/src/_components/account/transactions.tsx b/client/src/_components/account/transactions.tsx new file mode 100644 index 0000000..678d3c2 --- /dev/null +++ b/client/src/_components/account/transactions.tsx @@ -0,0 +1,68 @@ +import { TransactionAccordionItem } from "@/_components/account/transaction-accordion-item"; +import { Accordion } from "@/_components/ui/accordion"; +import { Button } from "@/_components/ui/button"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/_components/ui/card"; +import { Skeleton } from "@/_components/ui/skeleton"; +import { useTransactionsByChainId } from "@/_hooks/use-transactions"; +import { useAuth } from "@/_providers/auth-provider"; +import { ArrowRight } from "lucide-react"; +import { Link } from "react-router-dom"; +import { defaultNetwork } from "shared/constants/token"; + +export const Transactions = () => { + const { isSignedIn } = useAuth(); + + // Fetch transactions for the default network + const { data: transactions, isLoading: isLoadingTransactions } = + useTransactionsByChainId(defaultNetwork); + + // Get the 5 most recent transactions, sorted by timestamp + const recentTransactions = (transactions || []) + .sort((a, b) => b.timestamp - a.timestamp) + .slice(0, 5); + + return ( + + +
+ + Recent Transactions + + +
+
+ + {isLoadingTransactions ? ( +
+ + + +
+ ) : recentTransactions.length === 0 ? ( +
+

No recent transactions

+ {!isSignedIn && ( +

Sign in to view transactions

+ )} +
+ ) : ( + + {recentTransactions.map((tx) => ( + + ))} + + )} +
+
+ ); +}; diff --git a/client/src/components/app-sidebar.tsx b/client/src/_components/app-sidebar.tsx similarity index 83% rename from client/src/components/app-sidebar.tsx rename to client/src/_components/app-sidebar.tsx index 136c845..6aec14c 100644 --- a/client/src/components/app-sidebar.tsx +++ b/client/src/_components/app-sidebar.tsx @@ -7,10 +7,10 @@ import { SidebarMenuButton, SidebarMenuItem, useSidebar, -} from "@/components/ui/sidebar"; +} from "@/_components/ui/sidebar"; import { Link } from "react-router-dom"; import { Logo } from "./logo"; -import { useSideBarItems } from "@/hooks/use-sidebar-item"; +import { useSideBarItems } from "@/_hooks/use-sidebar-item"; export function AppSidebar() { const { open, isMobile, setOpenMobile } = useSidebar(); @@ -33,13 +33,15 @@ export function AppSidebar() { className={`flex flex-row justify-center items-center mt-4`} >
- +
{(open || isMobile) && ( -
-

commbank.eth

- +
+ + commbank.eth + + beta
diff --git a/client/src/components/signup/address-preview.tsx b/client/src/_components/auth/address-preview.tsx similarity index 100% rename from client/src/components/signup/address-preview.tsx rename to client/src/_components/auth/address-preview.tsx diff --git a/client/src/_components/auth/auth-button.tsx b/client/src/_components/auth/auth-button.tsx new file mode 100644 index 0000000..b8dc539 --- /dev/null +++ b/client/src/_components/auth/auth-button.tsx @@ -0,0 +1,56 @@ +import { SignupModal } from "@/_components/auth/signup-modal"; +import { Button } from "@/_components/ui/button"; +import { useDeviceCompatible } from "@/_hooks/use-device-compatible"; +import { useIsRegistered } from "@/_hooks/use-is-registered"; +import { useSignIn } from "@/_hooks/use-sign-in"; +import { useAuth } from "@/_providers/auth-provider"; +import { Loader2 } from "lucide-react"; +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; + +export const AuthButton = () => { + const navigate = useNavigate(); + const { isSignedIn } = useAuth(); + + const { data: isRegistered, isLoading: checkingRegistration } = + useIsRegistered(); + + const { isPasskeySupported, isDBSupported } = useDeviceCompatible(); + + const [showSignupModal, setShowSignupModal] = useState(false); + + const signInMutation = useSignIn(); + + const isLoading = signInMutation.isPending || checkingRegistration; + + const handleButtonClick = () => { + if (!isPasskeySupported || !isDBSupported) return; + + if (!isRegistered) { + setShowSignupModal(true); + } else if (isRegistered && !isSignedIn) { + signInMutation.mutate(); + } else if (isSignedIn) { + // Already signed in, just navigate to account page + navigate("/account"); + } + }; + return ( + <> + setShowSignupModal(false)} + /> + + + ); +}; diff --git a/client/src/components/signup/restore-account.tsx b/client/src/_components/auth/restore-account.tsx similarity index 95% rename from client/src/components/signup/restore-account.tsx rename to client/src/_components/auth/restore-account.tsx index 04e7500..5a61134 100644 --- a/client/src/components/signup/restore-account.tsx +++ b/client/src/_components/auth/restore-account.tsx @@ -1,18 +1,18 @@ import type { BackupFile, DerivedAddresses } from "@/_types"; -import { Button } from "@/components/ui/button"; +import { Button } from "@/_components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, -} from "@/components/ui/dialog"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { Textarea } from "@/components/ui/textarea"; +} from "@/_components/ui/dialog"; +import { Input } from "@/_components/ui/input"; +import { Label } from "@/_components/ui/label"; +import { Textarea } from "@/_components/ui/textarea"; import { deriveAddressesFromMnemonic, isValidMnemonic, -} from "@/lib/mnemonic-helpers"; +} from "@/lib/formatting/mnemonic-helpers"; import { Upload } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; diff --git a/client/src/components/signup/signup-modal.tsx b/client/src/_components/auth/signup-modal.tsx similarity index 92% rename from client/src/components/signup/signup-modal.tsx rename to client/src/_components/auth/signup-modal.tsx index f4a5d49..03944f6 100644 --- a/client/src/components/signup/signup-modal.tsx +++ b/client/src/_components/auth/signup-modal.tsx @@ -1,18 +1,18 @@ -import { Button } from "@/components/ui/button"; +import { Button } from "@/_components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, -} from "@/components/ui/dialog"; -import { useIsRegistered } from "@/hooks/use-is-registered"; -import { useAuth } from "@/lib/auth-context"; +} from "@/_components/ui/dialog"; +import { useIsRegistered } from "@/_hooks/use-is-registered"; +import { useAuth } from "@/_providers/auth-provider"; import { Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; import { RestoreAccount } from "./restore-account"; -import { useSignUp } from "@/hooks/use-sign-up"; +import { useSignUp } from "@/_hooks/use-sign-up"; interface SignupModalProps { isOpen: boolean; diff --git a/client/src/components/contacts/add-contact-modal.tsx b/client/src/_components/contacts/add-contact-modal.tsx similarity index 89% rename from client/src/components/contacts/add-contact-modal.tsx rename to client/src/_components/contacts/add-contact-modal.tsx index c3b461e..5a1bbbc 100644 --- a/client/src/components/contacts/add-contact-modal.tsx +++ b/client/src/_components/contacts/add-contact-modal.tsx @@ -1,16 +1,17 @@ -import { Button } from "@/components/ui/button"; -import { Checkbox } from "@/components/ui/checkbox"; +import { Button } from "@/_components/ui/button"; +import { Checkbox } from "@/_components/ui/checkbox"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, -} from "@/components/ui/dialog"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { useAddContact } from "@/hooks/use-contacts"; -import { isValidEthereumAddress } from "@/lib/validators"; +} from "@/_components/ui/dialog"; +import { Input } from "@/_components/ui/input"; +import { Label } from "@/_components/ui/label"; +import { useAddContact } from "@/_hooks/use-contacts"; +import { isValidEthereumAddress } from "@/lib/utils"; +import { DialogDescription } from "@radix-ui/react-dialog"; import { Info, UserPlus } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; @@ -125,8 +126,20 @@ export function AddContactModal({ children }: AddContactModalProps) { Add Contact + +

+ It's always easier to have a contact send your their + commbank.eth details, but you can manually enter contact details + below. +

+ +

+ When adding or editing a contact, you'll have to approve + account changes with a passkey approval. +

+
-
+
{/* Contact Name */}
GitHub Twitter diff --git a/client/src/components/layout.tsx b/client/src/_components/layout.tsx similarity index 61% rename from client/src/components/layout.tsx rename to client/src/_components/layout.tsx index ff9b80a..fa8fac3 100644 --- a/client/src/components/layout.tsx +++ b/client/src/_components/layout.tsx @@ -1,17 +1,22 @@ -import { AppSidebar } from "@/components/app-sidebar"; -import Footer from "@/components/footer"; -import PageHead from "@/components/page-head"; +import { AppSidebar } from "@/_components/app-sidebar"; +import Footer from "@/_components/footer"; +import { Logo } from "@/_components/logo"; import { SidebarProvider, SidebarTrigger, useSidebar, -} from "@/components/ui/sidebar"; -import { useAuth } from "@/lib/auth-context"; -import { PageTitleProvider, usePageTitle } from "@/lib/page-title-context"; +} from "@/_components/ui/sidebar"; +import { useAuth } from "@/_providers/auth-provider"; +import PageHead from "@/_providers/page-head"; +import { + PageTitleProvider, + usePageTitle, +} from "@/_providers/page-title-context"; import type React from "react"; import { useEffect, useState } from "react"; +import { Link, useLocation } from "react-router-dom"; import { Toaster } from "sonner"; -import { SettingsDropdown } from "./profile/settings-dropdown"; +import { SettingsDropdown } from "./settings/settings-dropdown"; function SidebarTriggerFixed() { const { open, isMobile } = useSidebar(); @@ -43,7 +48,7 @@ function SidebarTriggerFixed() { + {/* Background gradient that fades to transparent */} +
+ {/* Header content */} +
+ + + + commbank.eth + + +
+ + ); +} + +function MainContent({ children }: { children: React.ReactNode }) { + return ( +
+
{children}
+
+ ); +} + export function AppLayout({ children, }: Readonly<{ @@ -101,12 +140,9 @@ export function AppLayout({
+ -
-
- {children} -
-
+ {children}
diff --git a/client/src/components/logo.tsx b/client/src/_components/logo.tsx similarity index 100% rename from client/src/components/logo.tsx rename to client/src/_components/logo.tsx diff --git a/client/src/components/markdown.tsx b/client/src/_components/markdown.tsx similarity index 100% rename from client/src/components/markdown.tsx rename to client/src/_components/markdown.tsx diff --git a/client/src/_components/mobile-header.tsx b/client/src/_components/mobile-header.tsx new file mode 100644 index 0000000..11bb9e3 --- /dev/null +++ b/client/src/_components/mobile-header.tsx @@ -0,0 +1,36 @@ +import { Logo } from "@/_components/logo"; +import { SettingsDropdown } from "@/_components/settings/settings-dropdown"; +import { useAuth } from "@/_providers/auth-provider"; +import { Link } from "react-router-dom"; + +interface MobileHeaderProps { + showSettingsWhenSignedIn?: boolean; +} + +export function MobileHeader({ + showSettingsWhenSignedIn = true, +}: MobileHeaderProps) { + const { isSignedIn } = useAuth(); + + return ( + <> + {/* Background gradient that fades to transparent */} +
+ {/* Header content */} +
+ + + + commbank.eth + + +
+ {/* Settings dropdown - only show when signed in */} + {showSettingsWhenSignedIn && isSignedIn && ( +
+ +
+ )} + + ); +} diff --git a/client/src/components/settings/backup-account-modal.tsx b/client/src/_components/settings/backup-account-modal.tsx similarity index 78% rename from client/src/components/settings/backup-account-modal.tsx rename to client/src/_components/settings/backup-account-modal.tsx index 3df8b68..befd90d 100644 --- a/client/src/components/settings/backup-account-modal.tsx +++ b/client/src/_components/settings/backup-account-modal.tsx @@ -1,19 +1,16 @@ -import { Button } from "@/components/ui/button"; -import { Checkbox } from "@/components/ui/checkbox"; +import { Button } from "@/_components/ui/button"; +import { Checkbox } from "@/_components/ui/checkbox"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, -} from "@/components/ui/dialog"; -import { Label } from "@/components/ui/label"; -import { useAuth } from "@/lib/auth-context"; -import { - copyToClipboard, - downloadAsJson, - encryptMnemonicWithPin, -} from "@/lib/backup-helpers"; +} from "@/_components/ui/dialog"; +import { Label } from "@/_components/ui/label"; +import { useAuth } from "@/_providers/auth-provider"; +import { downloadAsJson } from "@/lib/utils"; +import { copyToClipboard } from "@/lib/utils"; import { AlertTriangle, Copy, Download } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; @@ -23,11 +20,6 @@ export function BackupAccountModal() { const [isOpen, setIsOpen] = useState(false); const [confirmExport, setConfirmExport] = useState(false); - const [addPin, setAddPin] = useState(true); - const [pin, setPin] = useState(""); - - // only show error if it's around the same length - const canExport = confirmExport; function waitForWindowFocus(): Promise { return new Promise((resolve) => { @@ -57,16 +49,7 @@ export function BackupAccountModal() { return; } - let exportData: string; - - if (addPin && pin) { - // Export encrypted with PIN - const encrypted = encryptMnemonicWithPin(mnemonic, pin); - exportData = JSON.stringify({ encryptedMnemonic: encrypted }, null, 2); - } else { - // Export plain mnemonic - exportData = JSON.stringify({ mnemonic }, null, 2); - } + const exportData = JSON.stringify({ mnemonic }, null, 2); // Wait for window focus before copying (in case passkey dialog lost focus) await waitForWindowFocus(); @@ -90,16 +73,7 @@ export function BackupAccountModal() { return; } - let exportData: Record; - - if (addPin && pin) { - // Export encrypted with PIN - const encrypted = encryptMnemonicWithPin(mnemonic, pin); - exportData = { encryptedMnemonic: encrypted }; - } else { - // Export plain mnemonic - exportData = { mnemonic }; - } + const exportData = { mnemonic }; downloadAsJson(exportData); toast.success("Account backup downloaded!"); @@ -113,8 +87,6 @@ export function BackupAccountModal() { const resetForm = () => { setConfirmExport(false); - setAddPin(true); - setPin(""); }; return ( @@ -172,7 +144,7 @@ export function BackupAccountModal() {
+ + + + Reset App Data + + This will clear your local cache and re-sync your account data. + + +
+ {/* Info */} +
+
+

What will be cleared:

+
    +
  • Cached notes and balances
  • +
  • Merkle tree data
  • +
  • Private transaction history
  • +
+

What will be kept:

+
    +
  • Your account credentials
  • +
  • Your contacts
  • +
  • Approval transactions
  • +
+
+
+ +

+ After reset, your account will automatically re-sync with the + indexers. This may take a moment. +

+ + {/* Action Buttons */} +
+ + +
+
+
+ + ); +} diff --git a/client/src/components/profile/settings-dropdown.tsx b/client/src/_components/settings/settings-dropdown.tsx similarity index 63% rename from client/src/components/profile/settings-dropdown.tsx rename to client/src/_components/settings/settings-dropdown.tsx index 9ecd693..b27e62f 100644 --- a/client/src/components/profile/settings-dropdown.tsx +++ b/client/src/_components/settings/settings-dropdown.tsx @@ -1,25 +1,48 @@ -import { Button } from "@/components/ui/button"; +import { Button } from "@/_components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { useAuth } from "@/lib/auth-context"; -import { LogOut, Settings, User } from "lucide-react"; +} from "@/_components/ui/dropdown-menu"; +import { useAuth } from "@/_providers/auth-provider"; +import { useQueryClient } from "@tanstack/react-query"; +import { LogOut, RefreshCw, Settings, User } from "lucide-react"; +import { useState } from "react"; import { Link, useNavigate } from "react-router-dom"; import { toast } from "sonner"; export function SettingsDropdown() { - const { isLoading, isSignedIn, signOut } = useAuth(); + const { isLoading, isSignedIn, signOut, refreshNotes } = useAuth(); const navigate = useNavigate(); + const queryClient = useQueryClient(); + const [isRefreshing, setIsRefreshing] = useState(false); + + const handleRefresh = async () => { + if (isRefreshing) return; + + setIsRefreshing(true); + try { + const newNotesCount = await refreshNotes(); + if (newNotesCount > 0) { + // Invalidate queries to refresh balances + queryClient.invalidateQueries({ queryKey: ["privateBalances"] }); + queryClient.invalidateQueries({ queryKey: ["notes"] }); + } else { + toast.success("Account is up to date"); + } + } catch (error) { + console.error("Failed to refresh:", error); + toast.error("Failed to refresh account"); + } finally { + setIsRefreshing(false); + } + }; const handleLogout = () => { signOut(); - toast.success("Logged out successfully", { - description: "Have a nice day!", - }); + toast.success("Logged out - Have a nice day!"); navigate("/"); }; @@ -78,6 +101,17 @@ export function SettingsDropdown() { + + + {isRefreshing ? "Refreshing..." : "Refresh Account"} + + { diff --git a/client/src/components/status/footer-status-indicator.tsx b/client/src/_components/status/footer-status-indicator.tsx similarity index 94% rename from client/src/components/status/footer-status-indicator.tsx rename to client/src/_components/status/footer-status-indicator.tsx index 8c0e794..51d663f 100644 --- a/client/src/components/status/footer-status-indicator.tsx +++ b/client/src/_components/status/footer-status-indicator.tsx @@ -1,7 +1,10 @@ import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { CheckCircle2, AlertCircle } from "lucide-react"; -import { checkRPCStatus, checkIndexerStatus } from "@/lib/status-helpers"; +import { + checkRPCStatus, + checkIndexerStatus, +} from "@/lib/formatting/status-helpers"; export function FooterStatusIndicator() { const [isOperational, setIsOperational] = useState(null); diff --git a/client/src/components/in-app-browser-warning.tsx b/client/src/_components/status/in-app-browser-warning.tsx similarity index 95% rename from client/src/components/in-app-browser-warning.tsx rename to client/src/_components/status/in-app-browser-warning.tsx index 999a8a1..508191e 100644 --- a/client/src/components/in-app-browser-warning.tsx +++ b/client/src/_components/status/in-app-browser-warning.tsx @@ -1,8 +1,12 @@ -import { Banner, BannerDescription, BannerTitle } from "@/components/ui/banner"; +import { + Banner, + BannerDescription, + BannerTitle, +} from "@/_components/ui/banner"; import { getInAppBrowserName, shouldShowInAppBrowserWarning, -} from "@/lib/browser-detection"; +} from "@/lib/device/browser-detection"; import { AlertTriangle } from "lucide-react"; import { useEffect, useState } from "react"; diff --git a/client/src/components/status/status-card.tsx b/client/src/_components/status/status-card.tsx similarity index 92% rename from client/src/components/status/status-card.tsx rename to client/src/_components/status/status-card.tsx index f8b656a..ea3fdaa 100644 --- a/client/src/components/status/status-card.tsx +++ b/client/src/_components/status/status-card.tsx @@ -1,5 +1,10 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Badge } from "@/components/ui/badge"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/_components/ui/card"; +import { Badge } from "@/_components/ui/badge"; import type { SystemStatus } from "@/_types"; import { CheckCircle2, AlertTriangle, XCircle, Loader2 } from "lucide-react"; diff --git a/client/src/_components/ui/accordion.tsx b/client/src/_components/ui/accordion.tsx new file mode 100644 index 0000000..a80a0db --- /dev/null +++ b/client/src/_components/ui/accordion.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDownIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +function Accordion({ + ...props +}: React.ComponentProps) { + return ; +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180 cursor-pointer", + className, + )} + {...props} + > + {children} + + + + ); +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ); +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/client/src/_components/ui/alert.tsx b/client/src/_components/ui/alert.tsx new file mode 100644 index 0000000..aa7de24 --- /dev/null +++ b/client/src/_components/ui/alert.tsx @@ -0,0 +1,66 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", + { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: + "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ); +} + +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ); +} + +export { Alert, AlertTitle, AlertDescription }; diff --git a/client/src/components/ui/badge.tsx b/client/src/_components/ui/badge.tsx similarity index 100% rename from client/src/components/ui/badge.tsx rename to client/src/_components/ui/badge.tsx diff --git a/client/src/components/ui/banner.tsx b/client/src/_components/ui/banner.tsx similarity index 100% rename from client/src/components/ui/banner.tsx rename to client/src/_components/ui/banner.tsx diff --git a/client/src/components/ui/button.tsx b/client/src/_components/ui/button.tsx similarity index 100% rename from client/src/components/ui/button.tsx rename to client/src/_components/ui/button.tsx diff --git a/client/src/components/ui/card.tsx b/client/src/_components/ui/card.tsx similarity index 100% rename from client/src/components/ui/card.tsx rename to client/src/_components/ui/card.tsx diff --git a/client/src/_components/ui/chart.tsx b/client/src/_components/ui/chart.tsx new file mode 100644 index 0000000..1769f24 --- /dev/null +++ b/client/src/_components/ui/chart.tsx @@ -0,0 +1,355 @@ +import * as React from "react"; +import * as RechartsPrimitive from "recharts"; + +import { cn } from "@/lib/utils"; + +// Format: { THEME_NAME: CSS_SELECTOR } +const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: React.ReactNode; + icon?: React.ComponentType; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +type ChartContextProps = { + config: ChartConfig; +}; + +const ChartContext = React.createContext(null); + +function useChart() { + const context = React.useContext(ChartContext); + + if (!context) { + throw new Error("useChart must be used within a "); + } + + return context; +} + +function ChartContainer({ + id, + className, + children, + config, + ...props +}: React.ComponentProps<"div"> & { + config: ChartConfig; + children: React.ComponentProps< + typeof RechartsPrimitive.ResponsiveContainer + >["children"]; +}) { + const uniqueId = React.useId(); + const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`; + + return ( + +
+ + + {children} + +
+
+ ); +} + +const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { + const colorConfig = Object.entries(config).filter( + ([, config]) => config.theme || config.color, + ); + + if (!colorConfig.length) { + return null; + } + + return ( + diff --git a/client/src/stories/assets/accessibility.png b/client/src/stories/assets/accessibility.png new file mode 100644 index 0000000..6ffe6fe Binary files /dev/null and b/client/src/stories/assets/accessibility.png differ diff --git a/client/src/stories/assets/accessibility.svg b/client/src/stories/assets/accessibility.svg new file mode 100644 index 0000000..107e93f --- /dev/null +++ b/client/src/stories/assets/accessibility.svg @@ -0,0 +1 @@ +Accessibility \ No newline at end of file diff --git a/client/src/stories/assets/addon-library.png b/client/src/stories/assets/addon-library.png new file mode 100644 index 0000000..95deb38 Binary files /dev/null and b/client/src/stories/assets/addon-library.png differ diff --git a/client/src/stories/assets/assets.png b/client/src/stories/assets/assets.png new file mode 100644 index 0000000..cfba681 Binary files /dev/null and b/client/src/stories/assets/assets.png differ diff --git a/client/src/stories/assets/avif-test-image.avif b/client/src/stories/assets/avif-test-image.avif new file mode 100644 index 0000000..530709b Binary files /dev/null and b/client/src/stories/assets/avif-test-image.avif differ diff --git a/client/src/stories/assets/context.png b/client/src/stories/assets/context.png new file mode 100644 index 0000000..e5cd249 Binary files /dev/null and b/client/src/stories/assets/context.png differ diff --git a/client/src/stories/assets/discord.svg b/client/src/stories/assets/discord.svg new file mode 100644 index 0000000..d638958 --- /dev/null +++ b/client/src/stories/assets/discord.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/src/stories/assets/docs.png b/client/src/stories/assets/docs.png new file mode 100644 index 0000000..a749629 Binary files /dev/null and b/client/src/stories/assets/docs.png differ diff --git a/client/src/stories/assets/figma-plugin.png b/client/src/stories/assets/figma-plugin.png new file mode 100644 index 0000000..8f79b08 Binary files /dev/null and b/client/src/stories/assets/figma-plugin.png differ diff --git a/client/src/stories/assets/github.svg b/client/src/stories/assets/github.svg new file mode 100644 index 0000000..dc51352 --- /dev/null +++ b/client/src/stories/assets/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/src/stories/assets/share.png b/client/src/stories/assets/share.png new file mode 100644 index 0000000..8097a37 Binary files /dev/null and b/client/src/stories/assets/share.png differ diff --git a/client/src/stories/assets/styling.png b/client/src/stories/assets/styling.png new file mode 100644 index 0000000..d341e82 Binary files /dev/null and b/client/src/stories/assets/styling.png differ diff --git a/client/src/stories/assets/testing.png b/client/src/stories/assets/testing.png new file mode 100644 index 0000000..d4ac39a Binary files /dev/null and b/client/src/stories/assets/testing.png differ diff --git a/client/src/stories/assets/theming.png b/client/src/stories/assets/theming.png new file mode 100644 index 0000000..1535eb9 Binary files /dev/null and b/client/src/stories/assets/theming.png differ diff --git a/client/src/stories/assets/tutorials.svg b/client/src/stories/assets/tutorials.svg new file mode 100644 index 0000000..b492a9c --- /dev/null +++ b/client/src/stories/assets/tutorials.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/src/stories/assets/youtube.svg b/client/src/stories/assets/youtube.svg new file mode 100644 index 0000000..a7515d7 --- /dev/null +++ b/client/src/stories/assets/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/src/stories/decorators.tsx b/client/src/stories/decorators.tsx new file mode 100644 index 0000000..4684a72 --- /dev/null +++ b/client/src/stories/decorators.tsx @@ -0,0 +1,94 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import type { Decorator } from "@storybook/react-vite"; +import React, { createContext } from "react"; + +// Create a fresh QueryClient for each story to avoid state leakage +const createTestQueryClient = () => + new QueryClient({ + defaultOptions: { + queries: { + // Disable retries in tests for faster feedback + retry: false, + // Don't refetch on window focus in tests + refetchOnWindowFocus: false, + }, + }, + }); + +// ============================================================================ +// Mock Auth Context - mirrors the real AuthProvider interface +// ============================================================================ + +interface AuthContextType { + isLoading: boolean; + isSignedIn: boolean; + token: string | null; + address: string | null; + privateAddress: string | null; + signingKey: string | null; + signIn: (mnemonic?: string) => Promise; + signOut: () => void; + getMnemonic: () => Promise; + getEnvelopeKey: () => Promise; + commbankDotEthAccount?: undefined; +} + +const MockAuthContext = createContext(undefined); + +const defaultMockAuth: AuthContextType = { + isLoading: false, + isSignedIn: true, + token: "mock-jwt-token", + address: "0x6e400024D346e8874080438756027001896937E3", + privateAddress: "0x1234567890abcdef1234567890abcdef12345678", + signingKey: "0xmocksigningkey", + signIn: async () => {}, + signOut: () => {}, + getMnemonic: async () => + "test test test test test test test test test test test junk", + getEnvelopeKey: async () => "0xmockenvelopekey", + commbankDotEthAccount: undefined, +}; + +function MockAuthProvider({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +// ============================================================================ +// Decorators +// ============================================================================ + +/** + * Decorator that provides QueryClient context for stories using React Query hooks + */ +export const withQueryClient: Decorator = (Story) => { + const queryClient = React.useMemo(() => createTestQueryClient(), []); + return ( + + + + ); +}; + +/** + * Combined decorator for components that need both Auth and QueryClient + * Uses a mock AuthProvider that doesn't have external dependencies + */ +export const withProviders: Decorator = (Story) => { + const queryClient = React.useMemo(() => createTestQueryClient(), []); + return ( + + + + + + ); +}; + +// Export the mock context so components can use it +// This is used by the module mock to replace the real useAuth +export { MockAuthContext }; diff --git a/client/src/stories/deposit.stories.ts b/client/src/stories/deposit.stories.ts new file mode 100644 index 0000000..daf78ea --- /dev/null +++ b/client/src/stories/deposit.stories.ts @@ -0,0 +1,35 @@ +import { InlineEncryptConfirmation } from "@/_components/PUM/inline-encrypt-confirmation"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { fn } from "storybook/test"; +import { mainnetAssets } from "shared/constants/token"; + +const meta = { + title: "Deposit", + component: InlineEncryptConfirmation, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], + args: { + // Use fn() for action logging - best practice for callback props + onCancel: fn(), + onSuccess: fn(), + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// Default story with USDC (first mainnet asset) +export const Default: Story = { + args: { + asset: mainnetAssets[0], + }, +}; + +// Story with ETH +export const WithETH: Story = { + args: { + asset: mainnetAssets.find((a) => a.symbol === "ETH") ?? mainnetAssets[0], + }, +}; diff --git a/client/src/stories/mocks/auth-provider.mock.tsx b/client/src/stories/mocks/auth-provider.mock.tsx new file mode 100644 index 0000000..54ba551 --- /dev/null +++ b/client/src/stories/mocks/auth-provider.mock.tsx @@ -0,0 +1,54 @@ +/** + * Mock implementation of auth-provider for Storybook + * This file replaces @/_providers/auth-provider in Storybook builds + */ +import React, { createContext, useContext } from "react"; + +interface AuthContextType { + isLoading: boolean; + isSignedIn: boolean; + token: string | null; + address: string | null; + privateAddress: string | null; + signingKey: string | null; + signIn: (mnemonic?: string) => Promise; + signOut: () => void; + getMnemonic: () => Promise; + getEnvelopeKey: () => Promise; + commbankDotEthAccount?: undefined; +} + +const AuthContext = createContext(undefined); + +const defaultMockAuth: AuthContextType = { + isLoading: false, + isSignedIn: true, + token: "mock-jwt-token", + address: "0x742d35Cc6634C0532925a3b844Bc9e7595f5bB91", + privateAddress: "0x1234567890abcdef1234567890abcdef12345678", + signingKey: "0xmocksigningkey", + signIn: async () => {}, + signOut: () => {}, + getMnemonic: async () => + "test test test test test test test test test test test junk", + getEnvelopeKey: async () => "0xmockenvelopekey", + commbankDotEthAccount: undefined, +}; + +export function AuthProvider({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +export function useAuth() { + const context = useContext(AuthContext); + if (context === undefined) { + // Return default mock values instead of throwing + // This allows components to work without being wrapped in a provider + return defaultMockAuth; + } + return context; +} diff --git a/client/src/stories/mocks/mock-auth-provider.tsx b/client/src/stories/mocks/mock-auth-provider.tsx new file mode 100644 index 0000000..0101b1f --- /dev/null +++ b/client/src/stories/mocks/mock-auth-provider.tsx @@ -0,0 +1,61 @@ +import React, { createContext, useContext } from "react"; + +interface MockAuthContextType { + isLoading: boolean; + isSignedIn: boolean; + token: string | null; + address: string | null; + privateAddress: string | null; + signingKey: string | null; + signIn: (mnemonic?: string) => Promise; + signOut: () => void; + getMnemonic: () => Promise; + getEnvelopeKey: () => Promise; + commbankDotEthAccount?: undefined; +} + +const MockAuthContext = createContext( + undefined, +); + +export interface MockAuthProviderProps { + children: React.ReactNode; + overrides?: Partial; +} + +const defaultMockAuth: MockAuthContextType = { + isLoading: false, + isSignedIn: true, + token: "mock-jwt-token", + address: "0x742d35Cc6634C0532925a3b844Bc9e7595f5bB91", + privateAddress: "0x1234567890abcdef1234567890abcdef12345678", + signingKey: "0xmocksigningkey", + signIn: async () => {}, + signOut: () => {}, + getMnemonic: async () => + "test test test test test test test test test test test junk", + getEnvelopeKey: async () => "0xmockenvelopekey", + commbankDotEthAccount: undefined, +}; + +export function MockAuthProvider({ + children, + overrides = {}, +}: MockAuthProviderProps) { + const value = { ...defaultMockAuth, ...overrides }; + + return ( + + {children} + + ); +} + +// This hook mirrors the real useAuth but uses the mock context +export function useMockAuth() { + const context = useContext(MockAuthContext); + if (context === undefined) { + throw new Error("useMockAuth must be used within a MockAuthProvider"); + } + return context; +} diff --git a/client/vite.config.ts b/client/vite.config.ts index 88a0639..b4c8897 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,11 +1,20 @@ +/// import path from "path"; import tailwindcss from "@tailwindcss/vite"; - import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { nodePolyfills } from "vite-plugin-node-polyfills"; // https://vite.dev/config/ +import { fileURLToPath } from "node:url"; +import { storybookTest } from "@storybook/addon-vitest/vitest-plugin"; +import { playwright } from "@vitest/browser-playwright"; +const dirname = + typeof __dirname !== "undefined" + ? __dirname + : path.dirname(fileURLToPath(import.meta.url)); + +// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon export default defineConfig({ plugins: [react(), tailwindcss(), nodePolyfills()], optimizeDeps: { @@ -18,4 +27,36 @@ export default defineConfig({ }, dedupe: ["react", "react-dom"], }, + // handy for ngrok + // server: { + // allowedHosts: ["*], + // }, + test: { + projects: [ + { + extends: true, + plugins: [ + // The plugin will run tests for the stories defined in your Storybook config + // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest + storybookTest({ + configDir: path.join(dirname, ".storybook"), + }), + ], + test: { + name: "storybook", + browser: { + enabled: true, + headless: true, + provider: playwright({}), + instances: [ + { + browser: "chromium", + }, + ], + }, + setupFiles: [".storybook/vitest.setup.ts"], + }, + }, + ], + }, }); diff --git a/client/vitest.shims.d.ts b/client/vitest.shims.d.ts new file mode 100644 index 0000000..03b1801 --- /dev/null +++ b/client/vitest.shims.d.ts @@ -0,0 +1 @@ +/// diff --git a/contracts/scripts/secrets.ts b/contracts/const/secrets.ts similarity index 100% rename from contracts/scripts/secrets.ts rename to contracts/const/secrets.ts diff --git a/contracts/contracts/CommBankDotEth.sol b/contracts/contracts/CommBankDotEth.sol index 7ad058f..7249dc3 100755 --- a/contracts/contracts/CommBankDotEth.sol +++ b/contracts/contracts/CommBankDotEth.sol @@ -1,6 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; + +import "./PoseidonMerkleTree.sol"; +import {IVerifier} from "./verifiers/DepositVerifier.sol"; + // ___. __ __ .__ // ____ ____ _____ _____\_ |__ _____ ____ | | __ _____/ |_| |__ // _/ ___\/ _ \ / \ / \| __ \\__ \ / \| |/ / _/ __ \ __\ | \ @@ -8,20 +14,11 @@ pragma solidity ^0.8.24; // \___ >____/|__|_| /__|_| /___ (____ /___| /__|_ \ /\ \___ >__| |___| / // \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ // -// author: benhooper.eth - -import "./PoseidonMerkleTree.sol"; - -import {IVerifier} from "./verifiers/DepositVerifier.sol"; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; - contract CommBankDotEth is PoseidonMerkleTree, AccessControl { address public depositVerifier; address public transferVerifier; address public withdrawVerifier; + address public transferExternalVerifier; mapping(bytes32 => bool) public nullifierUsed; @@ -41,11 +38,13 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { constructor( address _noteVerifier, address _transactVerifier, - address _withdrawalVerifier + address _withdrawalVerifier, + address _transferExternalVerifier ) PoseidonMerkleTree(12) { depositVerifier = _noteVerifier; transferVerifier = _transactVerifier; withdrawVerifier = _withdrawalVerifier; + transferExternalVerifier = _transferExternalVerifier; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(DEPOSIT_ROLE, msg.sender); @@ -56,7 +55,7 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { uint256 _amount, // with decimals bytes calldata _proof, bytes32[] calldata _publicInputs, - bytes[] calldata _payload + bytes[] calldata _payload // TODO this probably doesn't need to be an array ) public onlyRole(DEPOSIT_ROLE) { bool depositTransfer = IERC20(_erc20).transferFrom( msg.sender, @@ -65,14 +64,14 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { ); require(depositTransfer, "failed to transfer deposit"); - // VERIFY PROOF + // verify proof bool isValidProof = IVerifier(depositVerifier).verify( _proof, _publicInputs ); require(isValidProof, "Invalid deposit proof!"); - // CHECK INPUT ADDRESS AND AMOUNT MATCH PROOF INPUTS + // check input input asset address and amount match proof inputs require( _erc20 == address(uint160(uint256(_publicInputs[1]))), "ERC20 address mismatch" @@ -82,9 +81,10 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { "Address amount incorrect" ); - // INSERT NOTE INTO TREE + // insert note _insert(uint256(_publicInputs[0])); + // TODO this probably doesn't need to be a loop for (uint256 i = 0; i < 3 && i < _payload.length; i++) { if (_payload[i].length != 0) { emit NotePayload(_payload[i]); @@ -95,9 +95,9 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { function depositNative( bytes calldata _proof, bytes32[] calldata _publicInputs, - bytes[] calldata _payload + bytes[] calldata _payload // TODO this probably doesn't need to be an array ) public payable onlyRole(DEPOSIT_ROLE) { - // VERIFY PROOF + // verify proof bool isValidProof = IVerifier(depositVerifier).verify( _proof, _publicInputs @@ -112,10 +112,10 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { // check that msg.value matches amount in proof require(msg.value == uint64(uint256(_publicInputs[2])), "Amount incorrect"); - // Insert note into tree + // insert note _insert(uint256(_publicInputs[0])); - // Emit encrypted payloads + // TODO this probably doesn't need to be a loop for (uint256 i = 0; i < 3 && i < _payload.length; i++) { if (_payload[i].length != 0) { emit NotePayload(_payload[i]); @@ -153,7 +153,7 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { } } - // and insert output note commitments + // and insert output notes for ( uint256 i = NOTES_INPUT_LENGTH + 1; i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH; @@ -228,4 +228,83 @@ contract CommBankDotEth is PoseidonMerkleTree, AccessControl { } } } + + // transfer function that allows for arbitrary amounts of withdrawal (not just note based) + function transferExternal( + bytes calldata _proof, + bytes32[] calldata _publicInputs, + bytes[] calldata _payload + ) public { + // verify the root is in the trees history + require(isKnownRoot(uint256(_publicInputs[0])), "Invalid Root!"); + + // verify the proof + bool isValidProof = IVerifier(transferExternalVerifier).verify( + _proof, + _publicInputs + ); + require(isValidProof, "Invalid transfer external proof"); + + // Mark nullifiers as spent (indices 1-3) + for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) { + if (_publicInputs[i] != bytes32(0)) { + require( + nullifierUsed[_publicInputs[i]] == false, + "Nullifier already spent" + ); + nullifierUsed[_publicInputs[i]] = true; + emit NullifierUsed(_publicInputs[i]); + } + } + + // Process output notes (indices 4-6 are output_hashes) + // Insert internal transfer notes into merkle tree + for ( + uint256 i = NOTES_INPUT_LENGTH + 1; + i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH; + i++ + ) { + if (_publicInputs[i] != bytes32(0)) { + _insert(uint256(_publicInputs[i])); + } + } + + // Process external withdrawals (indices 7-9: exit_assets, 10-12: exit_amounts, 13-15: exit_addresses) + uint256 exitAssetStartIndex = 7; + uint256 exitAmountStartIndex = exitAssetStartIndex + NOTES_INPUT_LENGTH; + uint256 exitAddressStartIndex = exitAmountStartIndex + NOTES_INPUT_LENGTH; + + for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) { + uint256 assetIndex = exitAssetStartIndex + i; + uint256 amountIndex = exitAmountStartIndex + i; + uint256 addressIndex = exitAddressStartIndex + i; + + address exitAsset = address(uint160(uint256(_publicInputs[assetIndex]))); + uint256 exitAmount = uint256(_publicInputs[amountIndex]); + address exitAddress = address( + uint160(uint256(_publicInputs[addressIndex])) + ); + + if (exitAmount > 0 && exitAddress != address(0)) { + if (exitAsset == ETH_ADDRESS) { + require( + address(this).balance >= exitAmount, + "Insufficient ETH balance" + ); + (bool success, ) = exitAddress.call{value: exitAmount}(""); + require(success, "ETH transfer failed"); + } else { + bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount); + require(success, "Token transfer failed"); + } + } + } + + // Emit payload note parameters for internal transfers + for (uint256 i = 0; i < 3 && i < _payload.length; i++) { + if (_payload[i].length != 0) { + emit NotePayload(_payload[i]); + } + } + } } diff --git a/contracts/contracts/verifiers/TransferExternalVerifier.sol b/contracts/contracts/verifiers/TransferExternalVerifier.sol new file mode 100644 index 0000000..c535fa1 --- /dev/null +++ b/contracts/contracts/verifiers/TransferExternalVerifier.sol @@ -0,0 +1,2435 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Aztec +pragma solidity >=0.8.21; + +uint256 constant N = 16384; +uint256 constant LOG_N = 14; +uint256 constant NUMBER_OF_PUBLIC_INPUTS = 35; +uint256 constant VK_HASH = 0x0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a2988; +library HonkVerificationKey { + function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { + Honk.VerificationKey memory vk = Honk.VerificationKey({ + circuitSize: uint256(16384), + logCircuitSize: uint256(14), + publicInputsSize: uint256(35), + ql: Honk.G1Point({ + x: uint256(0x282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db746), + y: uint256(0x0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb746656) + }), + qr: Honk.G1Point({ + x: uint256(0x1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a), + y: uint256(0x147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f) + }), + qo: Honk.G1Point({ + x: uint256(0x26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b2), + y: uint256(0x15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f) + }), + q4: Honk.G1Point({ + x: uint256(0x2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d), + y: uint256(0x207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d) + }), + qm: Honk.G1Point({ + x: uint256(0x23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d9), + y: uint256(0x2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82) + }), + qc: Honk.G1Point({ + x: uint256(0x11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb), + y: uint256(0x1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881) + }), + qLookup: Honk.G1Point({ + x: uint256(0x1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf0), + y: uint256(0x299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f) + }), + qArith: Honk.G1Point({ + x: uint256(0x1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb23), + y: uint256(0x0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a349160) + }), + qDeltaRange: Honk.G1Point({ + x: uint256(0x19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a), + y: uint256(0x0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d95) + }), + qElliptic: Honk.G1Point({ + x: uint256(0x27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca), + y: uint256(0x16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3) + }), + qMemory: Honk.G1Point({ + x: uint256(0x13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d), + y: uint256(0x187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f46) + }), + qNnf: Honk.G1Point({ + x: uint256(0x178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f112), + y: uint256(0x30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31) + }), + qPoseidon2External: Honk.G1Point({ + x: uint256(0x207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b43), + y: uint256(0x26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f) + }), + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a), + y: uint256(0x1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f824) + }), + s1: Honk.G1Point({ + x: uint256(0x25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa), + y: uint256(0x27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce) + }), + s2: Honk.G1Point({ + x: uint256(0x232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a3), + y: uint256(0x049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c) + }), + s3: Honk.G1Point({ + x: uint256(0x274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c170773895124), + y: uint256(0x01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c86) + }), + s4: Honk.G1Point({ + x: uint256(0x2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d03), + y: uint256(0x20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba665792934) + }), + t1: Honk.G1Point({ + x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26), + y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f) + }), + t2: Honk.G1Point({ + x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e), + y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19) + }), + t3: Honk.G1Point({ + x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77), + y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7) + }), + t4: Honk.G1Point({ + x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce), + y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854) + }), + id1: Honk.G1Point({ + x: uint256(0x0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c76), + y: uint256(0x035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b) + }), + id2: Honk.G1Point({ + x: uint256(0x3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e), + y: uint256(0x25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770) + }), + id3: Honk.G1Point({ + x: uint256(0x0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c88), + y: uint256(0x2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b) + }), + id4: Honk.G1Point({ + x: uint256(0x04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f581), + y: uint256(0x0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e9) + }), + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + }), + lagrangeLast: Honk.G1Point({ + x: uint256(0x2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d), + y: uint256(0x1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b) + }) + }); + return vk; + } +} + +pragma solidity ^0.8.27; + +interface IVerifier { + function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool); +} + +type Fr is uint256; + +using {add as +} for Fr global; +using {sub as -} for Fr global; +using {mul as *} for Fr global; + +using {exp as ^} for Fr global; +using {notEqual as !=} for Fr global; +using {equal as ==} for Fr global; + +uint256 constant SUBGROUP_SIZE = 256; +uint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order +uint256 constant P = MODULUS; +Fr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76); +Fr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6); +Fr constant MINUS_ONE = Fr.wrap(MODULUS - 1); +Fr constant ONE = Fr.wrap(1); +Fr constant ZERO = Fr.wrap(0); +// Instantiation + +library FrLib { + function from(uint256 value) internal pure returns (Fr) { + unchecked { + return Fr.wrap(value % MODULUS); + } + } + + function fromBytes32(bytes32 value) internal pure returns (Fr) { + unchecked { + return Fr.wrap(uint256(value) % MODULUS); + } + } + + function toBytes32(Fr value) internal pure returns (bytes32) { + unchecked { + return bytes32(Fr.unwrap(value)); + } + } + + function invert(Fr value) internal view returns (Fr) { + uint256 v = Fr.unwrap(value); + uint256 result; + + // Call the modexp precompile to invert in the field + assembly { + let free := mload(0x40) + mstore(free, 0x20) + mstore(add(free, 0x20), 0x20) + mstore(add(free, 0x40), 0x20) + mstore(add(free, 0x60), v) + mstore(add(free, 0x80), sub(MODULUS, 2)) + mstore(add(free, 0xa0), MODULUS) + let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20) + if iszero(success) { + revert(0, 0) + } + result := mload(0x00) + mstore(0x40, add(free, 0x80)) + } + + return Fr.wrap(result); + } + + function pow(Fr base, uint256 v) internal view returns (Fr) { + uint256 b = Fr.unwrap(base); + uint256 result; + + // Call the modexp precompile to invert in the field + assembly { + let free := mload(0x40) + mstore(free, 0x20) + mstore(add(free, 0x20), 0x20) + mstore(add(free, 0x40), 0x20) + mstore(add(free, 0x60), b) + mstore(add(free, 0x80), v) + mstore(add(free, 0xa0), MODULUS) + let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20) + if iszero(success) { + revert(0, 0) + } + result := mload(0x00) + mstore(0x40, add(free, 0x80)) + } + + return Fr.wrap(result); + } + + function div(Fr numerator, Fr denominator) internal view returns (Fr) { + unchecked { + return numerator * invert(denominator); + } + } + + function sqr(Fr value) internal pure returns (Fr) { + unchecked { + return value * value; + } + } + + function unwrap(Fr value) internal pure returns (uint256) { + unchecked { + return Fr.unwrap(value); + } + } + + function neg(Fr value) internal pure returns (Fr) { + unchecked { + return Fr.wrap(MODULUS - Fr.unwrap(value)); + } + } +} + +// Free functions +function add(Fr a, Fr b) pure returns (Fr) { + unchecked { + return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS)); + } +} + +function mul(Fr a, Fr b) pure returns (Fr) { + unchecked { + return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS)); + } +} + +function sub(Fr a, Fr b) pure returns (Fr) { + unchecked { + return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS)); + } +} + +function exp(Fr base, Fr exponent) pure returns (Fr) { + if (Fr.unwrap(exponent) == 0) return Fr.wrap(1); + // Implement exponent with a loop as we will overflow otherwise + for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) { + base = base * base; + } + return base; +} + +function notEqual(Fr a, Fr b) pure returns (bool) { + unchecked { + return Fr.unwrap(a) != Fr.unwrap(b); + } +} + +function equal(Fr a, Fr b) pure returns (bool) { + unchecked { + return Fr.unwrap(a) == Fr.unwrap(b); + } +} + +uint256 constant CONST_PROOF_SIZE_LOG_N = 28; + +uint256 constant NUMBER_OF_SUBRELATIONS = 28; +uint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8; +uint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9; +uint256 constant NUMBER_OF_ENTITIES = 41; +uint256 constant NUMBER_UNSHIFTED = 36; +uint256 constant NUMBER_TO_BE_SHIFTED = 5; +uint256 constant PAIRING_POINTS_SIZE = 16; + +uint256 constant FIELD_ELEMENT_SIZE = 0x20; +uint256 constant GROUP_ELEMENT_SIZE = 0x40; + +// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1 +uint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1; + +// ENUM FOR WIRES +enum WIRE { + Q_M, + Q_C, + Q_L, + Q_R, + Q_O, + Q_4, + Q_LOOKUP, + Q_ARITH, + Q_RANGE, + Q_ELLIPTIC, + Q_MEMORY, + Q_NNF, + Q_POSEIDON2_EXTERNAL, + Q_POSEIDON2_INTERNAL, + SIGMA_1, + SIGMA_2, + SIGMA_3, + SIGMA_4, + ID_1, + ID_2, + ID_3, + ID_4, + TABLE_1, + TABLE_2, + TABLE_3, + TABLE_4, + LAGRANGE_FIRST, + LAGRANGE_LAST, + W_L, + W_R, + W_O, + W_4, + Z_PERM, + LOOKUP_INVERSES, + LOOKUP_READ_COUNTS, + LOOKUP_READ_TAGS, + W_L_SHIFT, + W_R_SHIFT, + W_O_SHIFT, + W_4_SHIFT, + Z_PERM_SHIFT +} + +library Honk { + struct G1Point { + uint256 x; + uint256 y; + } + + struct VerificationKey { + // Misc Params + uint256 circuitSize; + uint256 logCircuitSize; + uint256 publicInputsSize; + // Selectors + G1Point qm; + G1Point qc; + G1Point ql; + G1Point qr; + G1Point qo; + G1Point q4; + G1Point qLookup; // Lookup + G1Point qArith; // Arithmetic widget + G1Point qDeltaRange; // Delta Range sort + G1Point qMemory; // Memory + G1Point qNnf; // Non-native Field + G1Point qElliptic; // Auxillary + G1Point qPoseidon2External; + G1Point qPoseidon2Internal; + // Copy cnstraints + G1Point s1; + G1Point s2; + G1Point s3; + G1Point s4; + // Copy identity + G1Point id1; + G1Point id2; + G1Point id3; + G1Point id4; + // Precomputed lookup table + G1Point t1; + G1Point t2; + G1Point t3; + G1Point t4; + // Fixed first and last + G1Point lagrangeFirst; + G1Point lagrangeLast; + } + + struct RelationParameters { + // challenges + Fr eta; + Fr etaTwo; + Fr etaThree; + Fr beta; + Fr gamma; + // derived + Fr publicInputsDelta; + } + + struct Proof { + // Pairing point object + Fr[PAIRING_POINTS_SIZE] pairingPointObject; + // Free wires + G1Point w1; + G1Point w2; + G1Point w3; + G1Point w4; + // Lookup helpers - Permutations + G1Point zPerm; + // Lookup helpers - logup + G1Point lookupReadCounts; + G1Point lookupReadTags; + G1Point lookupInverses; + // Sumcheck + Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates; + Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations; + // Shplemini + G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms; + Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations; + G1Point shplonkQ; + G1Point kzgQuotient; + } + + struct ZKProof { + // Pairing point object + Fr[PAIRING_POINTS_SIZE] pairingPointObject; + // Commitments to wire polynomials + G1Point w1; + G1Point w2; + G1Point w3; + G1Point w4; + // Commitments to logup witness polynomials + G1Point lookupReadCounts; + G1Point lookupReadTags; + G1Point lookupInverses; + // Commitment to grand permutation polynomial + G1Point zPerm; + G1Point[3] libraCommitments; + // Sumcheck + Fr libraSum; + Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates; + Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations; + Fr libraEvaluation; + // ZK + G1Point geminiMaskingPoly; + Fr geminiMaskingEval; + // Shplemini + G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms; + Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations; + Fr[4] libraPolyEvals; + G1Point shplonkQ; + G1Point kzgQuotient; + } +} + +// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest +struct ZKTranscript { + // Oink + Honk.RelationParameters relationParameters; + Fr[NUMBER_OF_ALPHAS] alphas; + Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges; + // Sumcheck + Fr libraChallenge; + Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges; + // Shplemini + Fr rho; + Fr geminiR; + Fr shplonkNu; + Fr shplonkZ; + // Derived + Fr publicInputsDelta; +} + +library ZKTranscriptLib { + function generateTranscript( + Honk.ZKProof memory proof, + bytes32[] calldata publicInputs, + uint256 vkHash, + uint256 publicInputsSize, + uint256 logN + ) external pure returns (ZKTranscript memory t) { + Fr previousChallenge; + (t.relationParameters, previousChallenge) = + generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge); + + (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof); + + (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN); + (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof); + (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN); + + (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge); + + (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN); + + (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN); + + (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge); + return t; + } + + function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) { + uint256 challengeU256 = uint256(Fr.unwrap(challenge)); + uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + uint256 hi = challengeU256 >> 128; + first = FrLib.fromBytes32(bytes32(lo)); + second = FrLib.fromBytes32(bytes32(hi)); + } + + function generateRelationParametersChallenges( + Honk.ZKProof memory proof, + bytes32[] calldata publicInputs, + uint256 vkHash, + uint256 publicInputsSize, + Fr previousChallenge + ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) { + (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) = + generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize); + + (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof); + } + + function generateEtaChallenge( + Honk.ZKProof memory proof, + bytes32[] calldata publicInputs, + uint256 vkHash, + uint256 publicInputsSize + ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { + bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6); + round0[0] = bytes32(vkHash); + + for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) { + round0[1 + i] = bytes32(publicInputs[i]); + } + for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { + round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); + } + + // Create the first challenge + // Note: w4 is added to the challenge later on + round0[1 + publicInputsSize] = bytes32(proof.w1.x); + round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y); + round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x); + round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y); + round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x); + round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y); + + previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0))); + (eta, etaTwo) = splitChallenge(previousChallenge); + previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge)))); + + (etaThree,) = splitChallenge(previousChallenge); + } + + function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof) + internal + pure + returns (Fr beta, Fr gamma, Fr nextPreviousChallenge) + { + bytes32[7] memory round1; + round1[0] = FrLib.toBytes32(previousChallenge); + round1[1] = bytes32(proof.lookupReadCounts.x); + round1[2] = bytes32(proof.lookupReadCounts.y); + round1[3] = bytes32(proof.lookupReadTags.x); + round1[4] = bytes32(proof.lookupReadTags.y); + round1[5] = bytes32(proof.w4.x); + round1[6] = bytes32(proof.w4.y); + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1))); + (beta, gamma) = splitChallenge(nextPreviousChallenge); + } + + // Alpha challenges non-linearise the gate contributions + function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof) + internal + pure + returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge) + { + // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup + uint256[5] memory alpha0; + alpha0[0] = Fr.unwrap(previousChallenge); + alpha0[1] = proof.lookupInverses.x; + alpha0[2] = proof.lookupInverses.y; + alpha0[3] = proof.zPerm.x; + alpha0[4] = proof.zPerm.y; + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0))); + Fr alpha; + (alpha,) = splitChallenge(nextPreviousChallenge); + + // Compute powers of alpha for batching subrelations + alphas[0] = alpha; + for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) { + alphas[i] = alphas[i - 1] * alpha; + } + } + + function generateGateChallenges(Fr previousChallenge, uint256 logN) + internal + pure + returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge) + { + previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge)))); + (gateChallenges[0],) = splitChallenge(previousChallenge); + for (uint256 i = 1; i < logN; i++) { + gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1]; + } + nextPreviousChallenge = previousChallenge; + } + + function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof) + internal + pure + returns (Fr libraChallenge, Fr nextPreviousChallenge) + { + // 2 comm, 1 sum, 1 challenge + uint256[4] memory challengeData; + challengeData[0] = Fr.unwrap(previousChallenge); + challengeData[1] = proof.libraCommitments[0].x; + challengeData[2] = proof.libraCommitments[0].y; + challengeData[3] = Fr.unwrap(proof.libraSum); + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData))); + (libraChallenge,) = splitChallenge(nextPreviousChallenge); + } + + function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN) + internal + pure + returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge) + { + for (uint256 i = 0; i < logN; i++) { + Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal; + univariateChal[0] = prevChallenge; + + for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) { + univariateChal[j + 1] = proof.sumcheckUnivariates[i][j]; + } + prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal))); + + (sumcheckChallenges[i],) = splitChallenge(prevChallenge); + } + nextPreviousChallenge = prevChallenge; + } + + // We add Libra claimed eval + 3 comm + 1 more eval + function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge) + internal + pure + returns (Fr rho, Fr nextPreviousChallenge) + { + uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements; + rhoChallengeElements[0] = Fr.unwrap(prevChallenge); + uint256 i; + for (i = 1; i <= NUMBER_OF_ENTITIES; i++) { + rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]); + } + rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation); + + i += 1; + rhoChallengeElements[i] = proof.libraCommitments[1].x; + rhoChallengeElements[i + 1] = proof.libraCommitments[1].y; + i += 2; + rhoChallengeElements[i] = proof.libraCommitments[2].x; + rhoChallengeElements[i + 1] = proof.libraCommitments[2].y; + i += 2; + rhoChallengeElements[i] = proof.geminiMaskingPoly.x; + rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y; + + i += 2; + rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval); + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements))); + (rho,) = splitChallenge(nextPreviousChallenge); + } + + function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN) + internal + pure + returns (Fr geminiR, Fr nextPreviousChallenge) + { + uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1); + gR[0] = Fr.unwrap(prevChallenge); + + for (uint256 i = 0; i < logN - 1; i++) { + gR[1 + i * 2] = proof.geminiFoldComms[i].x; + gR[2 + i * 2] = proof.geminiFoldComms[i].y; + } + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR))); + + (geminiR,) = splitChallenge(nextPreviousChallenge); + } + + function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN) + internal + pure + returns (Fr shplonkNu, Fr nextPreviousChallenge) + { + uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4); + shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge); + + for (uint256 i = 1; i <= logN; i++) { + shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]); + } + + uint256 libraIdx = 0; + for (uint256 i = logN + 1; i <= logN + 4; i++) { + shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]); + libraIdx++; + } + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements))); + (shplonkNu,) = splitChallenge(nextPreviousChallenge); + } + + function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge) + internal + pure + returns (Fr shplonkZ, Fr nextPreviousChallenge) + { + uint256[3] memory shplonkZChallengeElements; + shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge); + + shplonkZChallengeElements[1] = proof.shplonkQ.x; + shplonkZChallengeElements[2] = proof.shplonkQ.y; + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements))); + (shplonkZ,) = splitChallenge(nextPreviousChallenge); + } + + function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) { + uint256 boundary = 0x0; + + // Pairing point object + for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { + p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + } + // Commitments + p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + + // Lookup / Permutation Helper Commitments + p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + + p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + // Sumcheck univariates + for (uint256 i = 0; i < logN; i++) { + for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) { + p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + } + } + + // Sumcheck evaluations + for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) { + p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + } + + p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + + p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + + // Gemini + // Read gemini fold univariates + for (uint256 i = 0; i < logN - 1; i++) { + p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + } + + // Read gemini a evaluations + for (uint256 i = 0; i < logN; i++) { + p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + } + + for (uint256 i = 0; i < 4; i++) { + p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]); + boundary += FIELD_ELEMENT_SIZE; + } + + // Shplonk + p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + boundary += GROUP_ELEMENT_SIZE; + // KZG + p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]); + } +} + +// Field arithmetic libraries + +library RelationsLib { + Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17) + + function accumulateRelationEvaluations( + Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations, + Honk.RelationParameters memory rp, + Fr[NUMBER_OF_ALPHAS] memory alphas, + Fr powPartialEval + ) internal pure returns (Fr accumulator) { + Fr[NUMBER_OF_SUBRELATIONS] memory evaluations; + + // Accumulate all relations in Ultra Honk - each with varying number of subrelations + accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval); + accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval); + accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval); + accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval); + accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval); + accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval); + accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval); + accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval); + accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval); + + // batch the subrelations with the alpha challenges to obtain the full honk relation + accumulator = scaleAndBatchSubrelations(evaluations, alphas); + } + + /** + * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids + * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code + * editors, and thus is noisy. + */ + function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) { + return p[uint256(_wire)]; + } + + uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000; + /** + * Ultra Arithmetic Relation + * + */ + + function accumulateArithmeticRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + // Relation 0 + Fr q_arith = wire(p, WIRE.Q_ARITH); + { + Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P); + + Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half; + accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R)) + + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C); + accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT); + accum = accum * q_arith; + accum = accum * domainSep; + evals[0] = accum; + } + + // Relation 1 + { + Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M); + accum = accum * (q_arith - Fr.wrap(2)); + accum = accum * (q_arith - ONE); + accum = accum * q_arith; + accum = accum * domainSep; + evals[1] = accum; + } + } + + function accumulatePermutationRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Honk.RelationParameters memory rp, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + Fr grand_product_numerator; + Fr grand_product_denominator; + + { + Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma; + num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma); + num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma); + num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma); + + grand_product_numerator = num; + } + { + Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma; + den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma); + den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma); + den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma); + + grand_product_denominator = den; + } + + // Contribution 2 + { + Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator; + + acc = acc + - ( + (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta)) + * grand_product_denominator + ); + acc = acc * domainSep; + evals[2] = acc; + } + + // Contribution 3 + { + Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep; + evals[3] = acc; + } + } + + function accumulateLogDerivativeLookupRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Honk.RelationParameters memory rp, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + Fr write_term; + Fr read_term; + + // Calculate the write term (the table accumulation) + { + write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta) + + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree); + } + + // Calculate the write term + { + Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT)); + Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT); + Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT); + + read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo) + + (wire(p, WIRE.Q_O) * rp.etaThree); + } + + Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term; + Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term; + + Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP) + - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP)); + + // Inverse calculated correctly relation + Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor; + accumulatorNone = accumulatorNone * domainSep; + + // Inverse + Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse; + + Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS); + + Fr read_tag_boolean_relation = read_tag * read_tag - read_tag; + + evals[4] = accumulatorNone; + evals[5] = accumulatorOne; + evals[6] = read_tag_boolean_relation * domainSep; + } + + function accumulateDeltaRangeRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + Fr minus_one = ZERO - ONE; + Fr minus_two = ZERO - Fr.wrap(2); + Fr minus_three = ZERO - Fr.wrap(3); + + // Compute wire differences + Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L); + Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R); + Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O); + Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4); + + // Contribution 6 + { + Fr acc = delta_1; + acc = acc * (delta_1 + minus_one); + acc = acc * (delta_1 + minus_two); + acc = acc * (delta_1 + minus_three); + acc = acc * wire(p, WIRE.Q_RANGE); + acc = acc * domainSep; + evals[7] = acc; + } + + // Contribution 7 + { + Fr acc = delta_2; + acc = acc * (delta_2 + minus_one); + acc = acc * (delta_2 + minus_two); + acc = acc * (delta_2 + minus_three); + acc = acc * wire(p, WIRE.Q_RANGE); + acc = acc * domainSep; + evals[8] = acc; + } + + // Contribution 8 + { + Fr acc = delta_3; + acc = acc * (delta_3 + minus_one); + acc = acc * (delta_3 + minus_two); + acc = acc * (delta_3 + minus_three); + acc = acc * wire(p, WIRE.Q_RANGE); + acc = acc * domainSep; + evals[9] = acc; + } + + // Contribution 9 + { + Fr acc = delta_4; + acc = acc * (delta_4 + minus_one); + acc = acc * (delta_4 + minus_two); + acc = acc * (delta_4 + minus_three); + acc = acc * wire(p, WIRE.Q_RANGE); + acc = acc * domainSep; + evals[10] = acc; + } + } + + struct EllipticParams { + // Points + Fr x_1; + Fr y_1; + Fr x_2; + Fr y_2; + Fr y_3; + Fr x_3; + // push accumulators into memory + Fr x_double_identity; + } + + function accumulateEllipticRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + EllipticParams memory ep; + ep.x_1 = wire(p, WIRE.W_R); + ep.y_1 = wire(p, WIRE.W_O); + + ep.x_2 = wire(p, WIRE.W_L_SHIFT); + ep.y_2 = wire(p, WIRE.W_4_SHIFT); + ep.y_3 = wire(p, WIRE.W_O_SHIFT); + ep.x_3 = wire(p, WIRE.W_R_SHIFT); + + Fr q_sign = wire(p, WIRE.Q_L); + Fr q_is_double = wire(p, WIRE.Q_M); + + // Contribution 10 point addition, x-coordinate check + // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 + Fr x_diff = (ep.x_2 - ep.x_1); + Fr y1_sqr = (ep.y_1 * ep.y_1); + { + // Move to top + Fr partialEval = domainSep; + + Fr y2_sqr = (ep.y_2 * ep.y_2); + Fr y1y2 = ep.y_1 * ep.y_2 * q_sign; + Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1); + x_add_identity = x_add_identity * x_diff * x_diff; + x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2; + + evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double); + } + + // Contribution 11 point addition, x-coordinate check + // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0 + { + Fr y1_plus_y3 = ep.y_1 + ep.y_3; + Fr y_diff = ep.y_2 * q_sign - ep.y_1; + Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff; + evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double); + } + + // Contribution 10 point doubling, x-coordinate check + // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0 + // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1 + { + Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1; + Fr y1_sqr_mul_4 = y1_sqr + y1_sqr; + y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4; + Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9); + + // NOTE: pushed into memory (stack >:'( ) + ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9; + + Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double; + evals[11] = evals[11] + acc; + } + + // Contribution 11 point doubling, y-coordinate check + // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0 + { + Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1; + Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3); + evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double; + } + } + + // Parameters used within the Memory Relation + // A struct is used to work around stack too deep. This relation has alot of variables + struct MemParams { + Fr memory_record_check; + Fr partial_record_check; + Fr next_gate_access_type; + Fr record_delta; + Fr index_delta; + Fr adjacent_values_match_if_adjacent_indices_match; + Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation; + Fr access_check; + Fr next_gate_access_type_is_boolean; + Fr ROM_consistency_check_identity; + Fr RAM_consistency_check_identity; + Fr timestamp_delta; + Fr RAM_timestamp_check_identity; + Fr memory_identity; + Fr index_is_monotonically_increasing; + } + + function accumulateMemoryRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Honk.RelationParameters memory rp, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + MemParams memory ap; + + /** + * MEMORY + * + * A RAM memory record contains a tuple of the following fields: + * * i: `index` of memory cell being accessed + * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM) + * * v: `value` of memory cell being accessed + * * a: `access` type of record. read: 0 = read, 1 = write + * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three + * + * A ROM memory record contains a tuple of the following fields: + * * i: `index` of memory cell being accessed + * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index) + * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index) + * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three + * + * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires + + * selectors, depending on whether the gate is a RAM read/write or a ROM read + * + * | gate type | i | v2/t | v | a | r | + * | --------- | -- | ----- | -- | -- | -- | + * | ROM | w1 | w2 | w3 | -- | w4 | + * | RAM | w1 | w2 | w3 | qc | w4 | + * + * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on + * `w2` to fix its value) + * + * + */ + + /** + * Memory Record Check + * Partial degree: 1 + * Total degree: 4 + * + * A ROM/ROM access gate can be evaluated with the identity: + * + * qc + w1 \eta + w2 \eta_two + w3 \eta_three - w4 = 0 + * + * For ROM gates, qc = 0 + */ + ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree; + ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo); + ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta); + ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C); + ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4 + ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4); + + /** + * Contribution 13 & 14 + * ROM Consistency Check + * Partial degree: 1 + * Total degree: 4 + * + * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of + * records that are sorted. + * + * We apply the following checks for the sorted records: + * + * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4 + * 2. index values for adjacent records are monotonically increasing + * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1} + * + */ + ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L); + ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4); + + ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2 + + ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2 + + evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)) + * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 + evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)) + * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 + + ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7 + + /** + * Contributions 15,16,17 + * RAM Consistency Check + * + * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check` + * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`. + * This is validated by requiring `access` to be boolean + * + * For two adjacent entries in the sorted list if _both_ + * A) index values match + * B) adjacent access value is 0 (i.e. next gate is a READ) + * then + * C) both values must match. + * The gate boolean check is + * (A && B) => C === !(A && B) || C === !A || !B || C + * + * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized + * with a WRITE operation. + */ + Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4 + ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8 + + // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta + // deg 1 or 4 + ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree; + ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo); + ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta); + ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type; + + Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O); + ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = + (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6 + + // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the + // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't + // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access + // type is correct, to cover this edge case + // deg 2 or 4 + ap.next_gate_access_type_is_boolean = + ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type; + + // Putting it all together... + evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation + * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8 + evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 + evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6 + + ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9 + + /** + * RAM Timestamp Consistency Check + * + * | w1 | w2 | w3 | w4 | + * | index | timestamp | timestamp_check | -- | + * + * Let delta_index = index_{i + 1} - index_{i} + * + * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i + * Else timestamp_check = 0 + */ + ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R); + ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3 + + /** + * Complete Contribution 12 + * The complete RAM/ROM memory identity + * Partial degree: + */ + ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6 + ap.memory_identity = + ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4 + ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6 + ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9 + + // (deg 3 or 9) + (deg 4) + (deg 3) + ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10 + evals[13] = ap.memory_identity; + } + + // Constants for the Non-native Field relation + Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68); + Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14); + + // Parameters used within the Non-Native Field Relation + // A struct is used to work around stack too deep. This relation has alot of variables + struct NnfParams { + Fr limb_subproduct; + Fr non_native_field_gate_1; + Fr non_native_field_gate_2; + Fr non_native_field_gate_3; + Fr limb_accumulator_1; + Fr limb_accumulator_2; + Fr nnf_identity; + } + + function accumulateNnfRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + NnfParams memory ap; + + /** + * Contribution 12 + * Non native field arithmetic gate 2 + * deg 4 + * + * _ _ + * / _ _ _ 14 \ + * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 | + * \_ _/ + * + * + */ + ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R); + ap.non_native_field_gate_2 = + (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT)); + ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE; + ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT); + ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct; + ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4); + + ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE; + ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT)); + ap.non_native_field_gate_1 = ap.limb_subproduct; + ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4)); + ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O); + + ap.non_native_field_gate_3 = ap.limb_subproduct; + ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4); + ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT)); + ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M); + + Fr non_native_field_identity = + ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3; + non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R); + + // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm + // deg 2 + ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT; + ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT); + ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT; + ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O); + ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT; + ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R); + ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT; + ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L); + ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4); + ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4); + + // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm + // deg 2 + ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT; + ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT); + ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT; + ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT); + ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT; + ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4); + ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT; + ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O); + ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT); + ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M); + + Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2; + limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3 + + ap.nnf_identity = non_native_field_identity + limb_accumulator_identity; + ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep); + evals[19] = ap.nnf_identity; + } + + struct PoseidonExternalParams { + Fr s1; + Fr s2; + Fr s3; + Fr s4; + Fr u1; + Fr u2; + Fr u3; + Fr u4; + Fr t0; + Fr t1; + Fr t2; + Fr t3; + Fr v1; + Fr v2; + Fr v3; + Fr v4; + Fr q_pos_by_scaling; + } + + function accumulatePoseidonExternalRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + PoseidonExternalParams memory ep; + + ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L); + ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R); + ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O); + ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4); + + ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1; + ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2; + ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3; + ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4; + // matrix mul v = M_E * u with 14 additions + ep.t0 = ep.u1 + ep.u2; // u_1 + u_2 + ep.t1 = ep.u3 + ep.u4; // u_3 + u_4 + ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2 + // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4 + ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4 + // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4 + ep.v4 = ep.t1 + ep.t1; + ep.v4 = ep.v4 + ep.v4 + ep.t3; + // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4 + ep.v2 = ep.t0 + ep.t0; + ep.v2 = ep.v2 + ep.v2 + ep.t2; + // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4 + ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4 + ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4 + + ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep; + evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT)); + + evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT)); + + evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT)); + + evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT)); + } + + struct PoseidonInternalParams { + Fr u1; + Fr u2; + Fr u3; + Fr u4; + Fr u_sum; + Fr v1; + Fr v2; + Fr v3; + Fr v4; + Fr s1; + Fr q_pos_by_scaling; + } + + function accumulatePoseidonInternalRelation( + Fr[NUMBER_OF_ENTITIES] memory p, + Fr[NUMBER_OF_SUBRELATIONS] memory evals, + Fr domainSep + ) internal pure { + PoseidonInternalParams memory ip; + + Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [ + FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7), + FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b), + FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15), + FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b) + ]; + + // add round constants + ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L); + + // apply s-box round + ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1; + ip.u2 = wire(p, WIRE.W_R); + ip.u3 = wire(p, WIRE.W_O); + ip.u4 = wire(p, WIRE.W_4); + + // matrix mul with v = M_I * u 4 muls and 7 additions + ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4; + + ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep; + + ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum; + evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT)); + + ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum; + evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT)); + + ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum; + evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT)); + + ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum; + evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT)); + } + + function scaleAndBatchSubrelations( + Fr[NUMBER_OF_SUBRELATIONS] memory evaluations, + Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges + ) internal pure returns (Fr accumulator) { + accumulator = evaluations[0]; + + for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) { + accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1]; + } + } +} + +// Field arithmetic libraries - prevent littering the code with modmul / addmul + +library CommitmentSchemeLib { + using FrLib for Fr; + + // Avoid stack too deep + struct ShpleminiIntermediates { + Fr unshiftedScalar; + Fr shiftedScalar; + Fr unshiftedScalarNeg; + Fr shiftedScalarNeg; + // Scalar to be multiplied by [1]₁ + Fr constantTermAccumulator; + // Accumulator for powers of rho + Fr batchingChallenge; + // Linear combination of multilinear (sumcheck) evaluations and powers of rho + Fr batchedEvaluation; + Fr[4] denominators; + Fr[4] batchingScalars; + // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated + Fr posInvertedDenominator; + // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated + Fr negInvertedDenominator; + // ν^{2i} * 1/(z - r^{2^i}) + Fr scalingFactorPos; + // ν^{2i+1} * 1/(z + r^{2^i}) + Fr scalingFactorNeg; + // Fold_i(r^{2^i}) reconstructed by Verifier + Fr[] foldPosEvaluations; + } + + function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) { + Fr[] memory squares = new Fr[](logN); + squares[0] = r; + for (uint256 i = 1; i < logN; ++i) { + squares[i] = squares[i - 1].sqr(); + } + return squares; + } + // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1 + + function computeFoldPosEvaluations( + Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges, + Fr batchedEvalAccumulator, + Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations, + Fr[] memory geminiEvalChallengePowers, + uint256 logSize + ) internal view returns (Fr[] memory) { + Fr[] memory foldPosEvaluations = new Fr[](logSize); + for (uint256 i = logSize; i > 0; --i) { + Fr challengePower = geminiEvalChallengePowers[i - 1]; + Fr u = sumcheckUChallenges[i - 1]; + + Fr batchedEvalRoundAcc = ( + (challengePower * batchedEvalAccumulator * Fr.wrap(2)) + - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u) + ); + // Divide by the denominator + batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert(); + + batchedEvalAccumulator = batchedEvalRoundAcc; + foldPosEvaluations[i - 1] = batchedEvalRoundAcc; + } + return foldPosEvaluations; + } +} + +uint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q + +function bytes32ToString(bytes32 value) pure returns (string memory result) { + bytes memory alphabet = "0123456789abcdef"; + + bytes memory str = new bytes(66); + str[0] = "0"; + str[1] = "x"; + for (uint256 i = 0; i < 32; i++) { + str[2 + i * 2] = alphabet[uint8(value[i] >> 4)]; + str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)]; + } + result = string(str); +} + +// Fr utility + +function bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) { + scalar = FrLib.fromBytes32(bytes32(proofSection)); +} + +// EC Point utilities +function bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) { + point = Honk.G1Point({ + x: uint256(bytes32(proofSection[0x00:0x20])) % Q, + y: uint256(bytes32(proofSection[0x20:0x40])) % Q + }); +} + +function negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) { + point.y = (Q - point.y) % Q; + return point; +} + +/** + * Convert the pairing points to G1 points. + * + * The pairing points are serialised as an array of 68 bit limbs representing two points + * The lhs of a pairing operation and the rhs of a pairing operation + * + * There are 4 fields for each group element, leaving 8 fields for each side of the pairing. + * + * @param pairingPoints The pairing points to convert. + * @return lhs + * @return rhs + */ +function convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints) + pure + returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs) +{ + uint256 lhsX = Fr.unwrap(pairingPoints[0]); + lhsX |= Fr.unwrap(pairingPoints[1]) << 68; + lhsX |= Fr.unwrap(pairingPoints[2]) << 136; + lhsX |= Fr.unwrap(pairingPoints[3]) << 204; + lhs.x = lhsX; + + uint256 lhsY = Fr.unwrap(pairingPoints[4]); + lhsY |= Fr.unwrap(pairingPoints[5]) << 68; + lhsY |= Fr.unwrap(pairingPoints[6]) << 136; + lhsY |= Fr.unwrap(pairingPoints[7]) << 204; + lhs.y = lhsY; + + uint256 rhsX = Fr.unwrap(pairingPoints[8]); + rhsX |= Fr.unwrap(pairingPoints[9]) << 68; + rhsX |= Fr.unwrap(pairingPoints[10]) << 136; + rhsX |= Fr.unwrap(pairingPoints[11]) << 204; + rhs.x = rhsX; + + uint256 rhsY = Fr.unwrap(pairingPoints[12]); + rhsY |= Fr.unwrap(pairingPoints[13]) << 68; + rhsY |= Fr.unwrap(pairingPoints[14]) << 136; + rhsY |= Fr.unwrap(pairingPoints[15]) << 204; + rhs.y = rhsY; +} + +/** + * Hash the pairing inputs from the present verification context with those extracted from the public inputs. + * + * @param proofPairingPoints Pairing points from the proof - (public inputs). + * @param accLhs Accumulator point for the left side - result of shplemini. + * @param accRhs Accumulator point for the right side - result of shplemini. + * @return recursionSeparator The recursion separator - generated from hashing the above. + */ +function generateRecursionSeparator( + Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints, + Honk.G1Point memory accLhs, + Honk.G1Point memory accRhs +) pure returns (Fr recursionSeparator) { + // hash the proof aggregated X + // hash the proof aggregated Y + // hash the accum X + // hash the accum Y + + (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints); + + uint256[8] memory recursionSeparatorElements; + + // Proof points + recursionSeparatorElements[0] = proofLhs.x; + recursionSeparatorElements[1] = proofLhs.y; + recursionSeparatorElements[2] = proofRhs.x; + recursionSeparatorElements[3] = proofRhs.y; + + // Accumulator points + recursionSeparatorElements[4] = accLhs.x; + recursionSeparatorElements[5] = accLhs.y; + recursionSeparatorElements[6] = accRhs.x; + recursionSeparatorElements[7] = accRhs.y; + + recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements))); +} + +/** + * G1 Mul with Separator + * Using the ecAdd and ecMul precompiles + * + * @param basePoint The point to multiply. + * @param other The other point to add. + * @param recursionSeperator The separator to use for the multiplication. + * @return `(recursionSeperator * basePoint) + other`. + */ +function mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator) + view + returns (Honk.G1Point memory) +{ + Honk.G1Point memory result; + + result = ecMul(recursionSeperator, basePoint); + result = ecAdd(result, other); + + return result; +} + +/** + * G1 Mul + * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result. + * + * @param value The value to multiply the point by. + * @param point The point to multiply. + * @return result The result of the multiplication. + */ +function ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) { + Honk.G1Point memory result; + + assembly { + let free := mload(0x40) + // Write the point into memory (two 32 byte words) + // Memory layout: + // Address | value + // free | point.x + // free + 0x20| point.y + mstore(free, mload(point)) + mstore(add(free, 0x20), mload(add(point, 0x20))) + // Write the scalar into memory (one 32 byte word) + // Memory layout: + // Address | value + // free + 0x40| value + mstore(add(free, 0x40), value) + + // Call the ecMul precompile, it takes in the following + // [point.x, point.y, scalar], and returns the result back into the free memory location. + let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40) + if iszero(success) { + revert(0, 0) + } + // Copy the result of the multiplication back into the result memory location. + // Memory layout: + // Address | value + // result | result.x + // result + 0x20| result.y + mstore(result, mload(free)) + mstore(add(result, 0x20), mload(add(free, 0x20))) + + mstore(0x40, add(free, 0x60)) + } + + return result; +} + +/** + * G1 Add + * Takes two G1 points and uses the ecAdd precompile to return the result. + * + * @param lhs The left hand side of the addition. + * @param rhs The right hand side of the addition. + * @return result The result of the addition. + */ +function ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) { + Honk.G1Point memory result; + + assembly { + let free := mload(0x40) + // Write lhs into memory (two 32 byte words) + // Memory layout: + // Address | value + // free | lhs.x + // free + 0x20| lhs.y + mstore(free, mload(lhs)) + mstore(add(free, 0x20), mload(add(lhs, 0x20))) + + // Write rhs into memory (two 32 byte words) + // Memory layout: + // Address | value + // free + 0x40| rhs.x + // free + 0x60| rhs.y + mstore(add(free, 0x40), mload(rhs)) + mstore(add(free, 0x60), mload(add(rhs, 0x20))) + + // Call the ecAdd precompile, it takes in the following + // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location. + let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40) + if iszero(success) { revert(0, 0) } + + // Copy the result of the addition back into the result memory location. + // Memory layout: + // Address | value + // result | result.x + // result + 0x20| result.y + mstore(result, mload(free)) + mstore(add(result, 0x20), mload(add(free, 0x20))) + + mstore(0x40, add(free, 0x80)) + } + + return result; +} + +function validateOnCurve(Honk.G1Point memory point) pure { + uint256 x = point.x; + uint256 y = point.y; + + bool success = false; + assembly { + let xx := mulmod(x, x, Q) + success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q)) + } + + require(success, "point is not on the curve"); +} + +function pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) { + bytes memory input = abi.encodePacked( + rhs.x, + rhs.y, + // Fixed G2 point + uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2), + uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed), + uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b), + uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa), + lhs.x, + lhs.y, + // G2 point from VK + uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1), + uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0), + uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4), + uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) + ); + + (bool success, bytes memory result) = address(0x08).staticcall(input); + decodedResult = success && abi.decode(result, (bool)); +} + +// Field arithmetic libraries - prevent littering the code with modmul / addmul + + + + +abstract contract BaseZKHonkVerifier is IVerifier { + using FrLib for Fr; + + uint256 immutable $N; + uint256 immutable $LOG_N; + uint256 immutable $VK_HASH; + uint256 immutable $NUM_PUBLIC_INPUTS; + + constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) { + $N = _N; + $LOG_N = _logN; + $VK_HASH = _vkHash; + $NUM_PUBLIC_INPUTS = _numPublicInputs; + } + + // Errors + error ProofLengthWrong(); + error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength); + error PublicInputsLengthWrong(); + error SumcheckFailed(); + error ShpleminiFailed(); + error GeminiChallengeInSubgroup(); + error ConsistencyCheckFailed(); + + // Constants for proof length calculation (matching UltraKeccakZKFlavor) + uint256 constant NUM_WITNESS_ENTITIES = 8; + uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points + uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements + uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations + + // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula) + function calculateProofSize(uint256 logN) internal pure returns (uint256) { + // Witness and Libra commitments + uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments + proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking + + // Sumcheck + proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates + proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations + + // Libra and Gemini + proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval + proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations + proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations + + // PCS commitments + proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments + proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments + + // Pairing points + proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs + + return proofLength; + } + + uint256 constant SHIFTED_COMMITMENTS_START = 30; + + function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory); + + function verify(bytes calldata proof, bytes32[] calldata publicInputs) + public + view + override + returns (bool verified) + { + // Calculate expected proof size based on $LOG_N + uint256 expectedProofSize = calculateProofSize($LOG_N); + + // Check the received proof is the expected size where each field element is 32 bytes + if (proof.length != expectedProofSize * 32) { + revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32); + } + + Honk.VerificationKey memory vk = loadVerificationKey(); + Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N); + + if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) { + revert PublicInputsLengthWrong(); + } + + // Generate the fiat shamir challenges for the whole protocol + ZKTranscript memory t = + ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N); + + // Derive public input delta + t.relationParameters.publicInputsDelta = computePublicInputDelta( + publicInputs, + p.pairingPointObject, + t.relationParameters.beta, + t.relationParameters.gamma, /*pubInputsOffset=*/ + 1 + ); + + // Sumcheck + if (!verifySumcheck(p, t)) revert SumcheckFailed(); + + if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed(); + + verified = true; + } + + uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28; + + function computePublicInputDelta( + bytes32[] memory publicInputs, + Fr[PAIRING_POINTS_SIZE] memory pairingPointObject, + Fr beta, + Fr gamma, + uint256 offset + ) internal view returns (Fr publicInputDelta) { + Fr numerator = Fr.wrap(1); + Fr denominator = Fr.wrap(1); + + Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset)); + Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1)); + + { + for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) { + Fr pubInput = FrLib.fromBytes32(publicInputs[i]); + + numerator = numerator * (numeratorAcc + pubInput); + denominator = denominator * (denominatorAcc + pubInput); + + numeratorAcc = numeratorAcc + beta; + denominatorAcc = denominatorAcc - beta; + } + + for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { + Fr pubInput = pairingPointObject[i]; + + numerator = numerator * (numeratorAcc + pubInput); + denominator = denominator * (denominatorAcc + pubInput); + + numeratorAcc = numeratorAcc + beta; + denominatorAcc = denominatorAcc - beta; + } + } + + // Fr delta = numerator / denominator; // TOOO: batch invert later? + publicInputDelta = FrLib.div(numerator, denominator); + } + + function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) { + Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0 + Fr powPartialEvaluation = Fr.wrap(1); + + // We perform sumcheck reductions over log n rounds ( the multivariate degree ) + for (uint256 round; round < $LOG_N; ++round) { + Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round]; + Fr totalSum = roundUnivariate[0] + roundUnivariate[1]; + if (totalSum != roundTargetSum) revert SumcheckFailed(); + + Fr roundChallenge = tp.sumCheckUChallenges[round]; + + // Update the round target for the next rounf + roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge); + powPartialEvaluation = + powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1))); + } + + // Last round + Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations( + proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation + ); + + Fr evaluation = Fr.wrap(1); + for (uint256 i = 2; i < $LOG_N; i++) { + evaluation = evaluation * tp.sumCheckUChallenges[i]; + } + + grandHonkRelationSum = + grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge; + verified = (grandHonkRelationSum == roundTargetSum); + } + + // Return the new target sum for the next sumcheck round + function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge) + internal + view + returns (Fr targetSum) + { + Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [ + Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80), + Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51), + Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0), + Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31), + Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240), + Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31), + Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0), + Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51), + Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80) + ]; + + // To compute the next target sum, we evaluate the given univariate at a point u (challenge). + + // Performing Barycentric evaluations + // Compute B(x) + Fr numeratorValue = Fr.wrap(1); + for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) { + numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i)); + } + + Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses; + for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) { + denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i))); + } + + for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) { + targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i]; + } + + // Scale the sum by the value of B(x) + targetSum = targetSum * numeratorValue; + } + + uint256 constant LIBRA_COMMITMENTS = 3; + uint256 constant LIBRA_EVALUATIONS = 4; + uint256 constant LIBRA_UNIVARIATES_LENGTH = 9; + + struct PairingInputs { + Honk.G1Point P_0; + Honk.G1Point P_1; + } + + function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp) + internal + view + returns (bool verified) + { + CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack + + // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size + Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N); + // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings + Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3); + Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3); + + mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert(); + mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert(); + + mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator); + mem.shiftedScalar = + tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator)); + + scalars[0] = Fr.wrap(1); + commitments[0] = proof.shplonkQ; + + /* Batch multivariate opening claims, shifted and unshifted + * The vector of scalars is populated as follows: + * \f[ + * \left( + * - \left(\frac{1}{z-r} + \nu \times \frac{1}{z+r}\right), + * \ldots, + * - \rho^{i+k-1} \times \left(\frac{1}{z-r} + \nu \times \frac{1}{z+r}\right), + * - \rho^{i+k} \times \frac{1}{r} \times \left(\frac{1}{z-r} - \nu \times \frac{1}{z+r}\right), + * \ldots, + * - \rho^{k+m-1} \times \frac{1}{r} \times \left(\frac{1}{z-r} - \nu \times \frac{1}{z+r}\right) + * \right) + * \f] + * + * The following vector is concatenated to the vector of commitments: + * \f[ + * f_0, \ldots, f_{m-1}, f_{\text{shift}, 0}, \ldots, f_{\text{shift}, k-1} + * \f] + * + * Simultaneously, the evaluation of the multilinear polynomial + * \f[ + * \sum \rho^i \cdot f_i + \sum \rho^{i+k} \cdot f_{\text{shift}, i} + * \f] + * at the challenge point \f$ (u_0,\ldots, u_{n-1}) \f$ is computed. + * + * This approach minimizes the number of iterations over the commitments to multilinear polynomials + * and eliminates the need to store the powers of \f$ \rho \f$. + */ + mem.batchedEvaluation = proof.geminiMaskingEval; + mem.batchingChallenge = tp.rho; + mem.unshiftedScalarNeg = mem.unshiftedScalar.neg(); + mem.shiftedScalarNeg = mem.shiftedScalar.neg(); + + scalars[1] = mem.unshiftedScalarNeg; + for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) { + scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge; + mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge); + mem.batchingChallenge = mem.batchingChallenge * tp.rho; + } + // g commitments are accumulated at r + // For each of the to be shifted commitments perform the shift in place by + // adding to the unshifted value. + // We do so, as the values are to be used in batchMul later, and as + // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute. + // Applied to w1, w2, w3, w4 and zPerm + for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) { + uint256 scalarOff = i + SHIFTED_COMMITMENTS_START; + uint256 evaluationOff = i + NUMBER_UNSHIFTED; + + scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge); + mem.batchedEvaluation = + mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge); + mem.batchingChallenge = mem.batchingChallenge * tp.rho; + } + + commitments[1] = proof.geminiMaskingPoly; + + commitments[2] = vk.qm; + commitments[3] = vk.qc; + commitments[4] = vk.ql; + commitments[5] = vk.qr; + commitments[6] = vk.qo; + commitments[7] = vk.q4; + commitments[8] = vk.qLookup; + commitments[9] = vk.qArith; + commitments[10] = vk.qDeltaRange; + commitments[11] = vk.qElliptic; + commitments[12] = vk.qMemory; + commitments[13] = vk.qNnf; + commitments[14] = vk.qPoseidon2External; + commitments[15] = vk.qPoseidon2Internal; + commitments[16] = vk.s1; + commitments[17] = vk.s2; + commitments[18] = vk.s3; + commitments[19] = vk.s4; + commitments[20] = vk.id1; + commitments[21] = vk.id2; + commitments[22] = vk.id3; + commitments[23] = vk.id4; + commitments[24] = vk.t1; + commitments[25] = vk.t2; + commitments[26] = vk.t3; + commitments[27] = vk.t4; + commitments[28] = vk.lagrangeFirst; + commitments[29] = vk.lagrangeLast; + + // Accumulate proof points + commitments[30] = proof.w1; + commitments[31] = proof.w2; + commitments[32] = proof.w3; + commitments[33] = proof.w4; + commitments[34] = proof.zPerm; + commitments[35] = proof.lookupInverses; + commitments[36] = proof.lookupReadCounts; + commitments[37] = proof.lookupReadTags; + + /* Batch gemini claims from the prover + * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from + * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars + * + * 1. Moves the vector + * \f[ + * \left( \text{com}(A_1), \text{com}(A_2), \ldots, \text{com}(A_{n-1}) \right) + * \f] + * to the 'commitments' vector. + * + * 2. Computes the scalars: + * \f[ + * \frac{\nu^{2}}{z + r^2}, \frac{\nu^3}{z + r^4}, \ldots, \frac{\nu^{n-1}}{z + r^{2^{n-1}}} + * \f] + * and places them into the 'scalars' vector. + * + * 3. Accumulates the summands of the constant term: + * \f[ + * \sum_{i=2}^{n-1} \frac{\nu^{i} \cdot A_i(-r^{2^i})}{z + r^{2^i}} + * \f] + * and adds them to the 'constant_term_accumulator'. + */ + + // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator: + // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1 + Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations( + tp.sumCheckUChallenges, + mem.batchedEvaluation, + proof.geminiAEvaluations, + powers_of_evaluation_challenge, + $LOG_N + ); + + mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator; + mem.constantTermAccumulator = + mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator); + + mem.batchingChallenge = tp.shplonkNu.sqr(); + uint256 boundary = NUMBER_UNSHIFTED + 2; + + // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1; + // Compute scalar multipliers for each fold commitment + for (uint256 i = 0; i < $LOG_N - 1; ++i) { + bool dummy_round = i >= ($LOG_N - 1); + + if (!dummy_round) { + // Update inverted denominators + mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert(); + mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert(); + + // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ] + mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator; + mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator; + scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg(); + + // Accumulate the const term contribution given by + // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l}) + Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1]; + accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1]; + mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution; + } + // Update the running power of v + mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu; + + commitments[boundary + i] = proof.geminiFoldComms[i]; + } + + boundary += $LOG_N - 1; + + // Finalize the batch opening claim + mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR); + mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR); + mem.denominators[2] = mem.denominators[0]; + mem.denominators[3] = mem.denominators[0]; + + mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu; + for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) { + Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge; + mem.batchingScalars[i] = scalingFactor.neg(); + mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu; + mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i]; + } + scalars[boundary] = mem.batchingScalars[0]; + scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2]; + scalars[boundary + 2] = mem.batchingScalars[3]; + + for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) { + commitments[boundary++] = proof.libraCommitments[i]; + } + + commitments[boundary] = Honk.G1Point({x: 1, y: 2}); + scalars[boundary++] = mem.constantTermAccumulator; + + if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) { + revert ConsistencyCheckFailed(); + } + + Honk.G1Point memory quotient_commitment = proof.kzgQuotient; + + commitments[boundary] = quotient_commitment; + scalars[boundary] = tp.shplonkZ; // evaluation challenge + + PairingInputs memory pair; + pair.P_0 = batchMul(commitments, scalars); + pair.P_1 = negateInplace(quotient_commitment); + + // Aggregate pairing points + Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1); + (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) = + convertPairingPointsToG1(proof.pairingPointObject); + + // Validate the points from the proof are on the curve + validateOnCurve(P_0_other); + validateOnCurve(P_1_other); + + // accumulate with aggregate points in proof + pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator); + pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator); + + return pairing(pair.P_0, pair.P_1); + } + + struct SmallSubgroupIpaIntermediates { + Fr[SUBGROUP_SIZE] challengePolyLagrange; + Fr challengePolyEval; + Fr lagrangeFirst; + Fr lagrangeLast; + Fr rootPower; + Fr[SUBGROUP_SIZE] denominators; // this has to disappear + Fr diff; + } + + function checkEvalsConsistency( + Fr[LIBRA_EVALUATIONS] memory libraPolyEvals, + Fr geminiR, + Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges, + Fr libraEval + ) internal view returns (bool check) { + Fr one = Fr.wrap(1); + Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one; + if (vanishingPolyEval == Fr.wrap(0)) { + revert GeminiChallengeInSubgroup(); + } + + SmallSubgroupIpaIntermediates memory mem; + mem.challengePolyLagrange[0] = one; + for (uint256 round = 0; round < $LOG_N; round++) { + uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round; + mem.challengePolyLagrange[currIdx] = one; + for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) { + mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round]; + } + } + + mem.rootPower = one; + mem.challengePolyEval = Fr.wrap(0); + for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) { + mem.denominators[idx] = mem.rootPower * geminiR - one; + mem.denominators[idx] = mem.denominators[idx].invert(); + mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx]; + mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE; + } + + Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert(); + mem.challengePolyEval = mem.challengePolyEval * numerator; + mem.lagrangeFirst = mem.denominators[0] * numerator; + mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator; + + mem.diff = mem.lagrangeFirst * libraPolyEvals[2]; + + mem.diff = mem.diff + + (geminiR - SUBGROUP_GENERATOR_INVERSE) + * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval); + mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3]; + + check = mem.diff == Fr.wrap(0); + } + + // This implementation is the same as above with different constants + function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars) + internal + view + returns (Honk.G1Point memory result) + { + uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3; + + // Validate all points are on the curve + for (uint256 i = 0; i < limit; ++i) { + validateOnCurve(base[i]); + } + + bool success = true; + assembly { + let free := mload(0x40) + + let count := 0x01 + for {} lt(count, add(limit, 1)) { count := add(count, 1) } { + // Get loop offsets + let base_base := add(base, mul(count, 0x20)) + let scalar_base := add(scalars, mul(count, 0x20)) + + mstore(add(free, 0x40), mload(mload(base_base))) + mstore(add(free, 0x60), mload(add(0x20, mload(base_base)))) + // Add scalar + mstore(add(free, 0x80), mload(scalar_base)) + + success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40)) + } + + // Return the result + mstore(result, mload(free)) + mstore(add(result, 0x20), mload(add(free, 0x20))) + } + + require(success, ShpleminiFailed()); + } +} + +contract TransferExternalVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { + function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { + return HonkVerificationKey.loadVerificationKey(); + } +} diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 3b9053b..2c84bba 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -33,10 +33,23 @@ export default defineConfig({ }, networks: { + mainnet: { + type: "http", + url: process.env.MAINNET_RPC_URL!, + accounts: [process.env.EVM_PRIVATE_KEY!], + chainId: 1, + }, sepolia: { type: "http", url: process.env.SEPOLIA_RPC_URL!, accounts: [process.env.EVM_PRIVATE_KEY!], + chainId: 11155111, + }, + arbSepolia: { + type: "http", + url: process.env.ARB_SEPOLIA_RPC_URL!, + accounts: [process.env.EVM_PRIVATE_KEY!], + chainId: 421614, }, }, verify: { diff --git a/contracts/helpers/functions/transfer.ts b/contracts/helpers/functions/transfer.ts index d2888b4..1f3dc2c 100755 --- a/contracts/helpers/functions/transfer.ts +++ b/contracts/helpers/functions/transfer.ts @@ -103,3 +103,72 @@ export const createDepositPayload = async ( return await encodeEncryptedPayload([encryptedNote, "0x", "0x"]); }; + +export const getTransferExternalDetails = async ( + tree: PoseidonMerkleTree, + inputNotes: InputNote[], + nullifiers: (bigint | string)[], + outputNotes: OutputNote[], + outputHashes: (bigint | string)[], + exitAssets: (bigint | string)[], + exitAmounts: (bigint | string)[], + exitAddresses: (bigint | string)[], + exitAddressHashes: (bigint | string)[], +) => { + const { transferExternalNoir, transferExternalBackend } = getNoirClasses(); + + const root = await tree.getRoot(); + + const { witness: transferExternalWitness } = + await transferExternalNoir.execute({ + root: root.toString(), + input_notes: inputNotes as any, + output_notes: outputNotes as any, + nullifiers: nullifiers.map((item) => item.toString()), + output_hashes: outputHashes.map((item) => item.toString()), + exit_assets: exitAssets.map((item) => item.toString()), + exit_amounts: exitAmounts.map((item) => item.toString()), + exit_addresses: exitAddresses.map((item) => item.toString()), + exit_address_hashes: exitAddressHashes.map((item) => item.toString()), + }); + + const transferExternalProof = await transferExternalBackend.generateProof( + transferExternalWitness, + { + keccakZK: true, + }, + ); + + return { + proof: transferExternalProof, + }; +}; + +export const transferExternal = async ( + commbankDotEth: CommBankDotEth, + proof: ProofData, + runner: ethers.Signer, + encryptedNotes?: (EncryptedNote | "0x")[], +) => { + const payload: string[] = []; + + if (encryptedNotes) { + for (const note of encryptedNotes) { + if (note === "0x" || !note) { + payload.push("0x"); + } else { + const encodedNote = ethers.AbiCoder.defaultAbiCoder().encode( + ["string", "string", "string", "string"], + [note.encryptedSecret, note.owner, note.asset_id, note.asset_amount], + ); + payload.push(encodedNote); + } + } + } + + const tx = await commbankDotEth + .connect(runner) + .transferExternal(proof.proof, proof.publicInputs, payload); + + return tx; +}; diff --git a/contracts/helpers/get-testing-api.ts b/contracts/helpers/get-testing-api.ts index 7ec18a4..934da05 100755 --- a/contracts/helpers/get-testing-api.ts +++ b/contracts/helpers/get-testing-api.ts @@ -41,8 +41,8 @@ export const getTestingAPI = async () => { transferBackend, withdrawNoir, withdrawBackend, - warpNoir, - warpBackend, + transferExternalNoir, + transferExternalBackend, } = getNoirClasses(); const tree = await getMerkleTree(); @@ -57,8 +57,8 @@ export const getTestingAPI = async () => { transferBackend, withdrawNoir, withdrawBackend, - warpNoir, - warpBackend, + transferExternalNoir, + transferExternalBackend, Signers, tree, deployer1Secret, diff --git a/contracts/helpers/note-formatting.ts b/contracts/helpers/note-formatting.ts index 48e4fd2..7a91a80 100755 --- a/contracts/helpers/note-formatting.ts +++ b/contracts/helpers/note-formatting.ts @@ -36,13 +36,15 @@ export const createOutputNote = ( secret: bigint | string, assetId: bigint | string, assetAmount: bigint | string, + externalAddress?: bigint | string, ) => { return { owner: owner.toString(), secret: secret.toString(), asset_id: assetId.toString(), asset_amount: assetAmount.toString(), + external_address: (externalAddress ?? 0n).toString(), }; }; -export const emptyOutputNote = createOutputNote(0n, 0n, 0n, 0n); +export const emptyOutputNote = createOutputNote(0n, 0n, 0n, 0n, 0n); diff --git a/contracts/helpers/objects/get-noir-classes.ts b/contracts/helpers/objects/get-noir-classes.ts index 1af9219..8833a5d 100755 --- a/contracts/helpers/objects/get-noir-classes.ts +++ b/contracts/helpers/objects/get-noir-classes.ts @@ -4,7 +4,7 @@ import { Noir } from "@noir-lang/noir_js"; import depositCircuit from "../../../circuits/deposit/target/deposit.json"; import transferCircuit from "../../../circuits/transfer/target/transfer.json"; import withdrawCircuit from "../../../circuits/withdraw/target/withdraw.json"; -import warpCircuit from "../../../circuits/warp/target/warp.json"; +import transferExternalCircuit from "../../../circuits/transfer_external/target/transfer_external.json"; export const getNoirClasses = () => { // @ts-expect-error no idea @@ -20,8 +20,10 @@ export const getNoirClasses = () => { const withdrawBackend = new UltraHonkBackend(withdrawCircuit.bytecode); // @ts-expect-error no idea - const warpNoir = new Noir(warpCircuit); - const warpBackend = new UltraHonkBackend(warpCircuit.bytecode); + const transferExternalNoir = new Noir(transferExternalCircuit); + const transferExternalBackend = new UltraHonkBackend( + transferExternalCircuit.bytecode, + ); return { depositNoir, @@ -30,7 +32,7 @@ export const getNoirClasses = () => { transferBackend, withdrawNoir, withdrawBackend, - warpNoir, - warpBackend, + transferExternalNoir, + transferExternalBackend, }; }; diff --git a/contracts/ignition/deployments/chain-1/artifacts/commbankDotEth#CommBankDotEth.json b/contracts/ignition/deployments/chain-1/artifacts/commbankDotEth#CommBankDotEth.json new file mode 100644 index 0000000..d2ad067 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/commbankDotEth#CommBankDotEth.json @@ -0,0 +1,786 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "CommBankDotEth", + "sourceName": "contracts/CommBankDotEth.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_noteVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_transactVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawalVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_transferExternalVerifier", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "leafIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "leafValue", + "type": "bytes32" + } + ], + "name": "LeafInserted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "encryptedNote", + "type": "bytes" + } + ], + "name": "NotePayload", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "nullifier", + "type": "bytes32" + } + ], + "name": "NullifierUsed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEPOSIT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_ROOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LEAF_INDEX", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ROOT_HISTORY_SIZE", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentRootIndex", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deployer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_erc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "depositNative", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "filledSubtrees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_left", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_right", + "type": "uint256" + } + ], + "name": "hashLeftRight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "height", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_root", + "type": "uint256" + } + ], + "name": "isKnownRoot", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "nullifierUsed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poseidon2Hasher", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "roots", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_hasher", + "type": "address" + } + ], + "name": "setPoseidon", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "transferExternal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferExternalVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "i", + "type": "uint256" + } + ], + "name": "zeros", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", + "deployedBytecode": "0x6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": { + "576": [ + { + "length": 32, + "start": 1225 + }, + { + "length": 32, + "start": 2904 + }, + { + "length": 32, + "start": 5813 + }, + { + "length": 32, + "start": 6550 + } + ], + "1525": [ + { + "length": 32, + "start": 574 + }, + { + "length": 32, + "start": 7925 + } + ] + }, + "inputSourceName": "project/contracts/CommBankDotEth.sol", + "buildInfoId": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifier.json b/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifier.json new file mode 100644 index 0000000..b6ce8d1 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "DepositVerifier", + "sourceName": "contracts/verifiers/DepositVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$848e18252827b7ad91b03e1d1be9251966$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$848e18252827b7ad91b03e1d1be9251966$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/DepositVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/DepositVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11157 + }, + { + "length": 32, + "start": 11966 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/DepositVerifier.sol", + "buildInfoId": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifierLib.json b/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifierLib.json new file mode 100644 index 0000000..a881b33 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/depositVerifier#DepositVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/DepositVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/DepositVerifier.sol", + "buildInfoId": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferExternalVerifier.json b/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferExternalVerifier.json new file mode 100644 index 0000000..f76e480 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferExternalVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "TransferExternalVerifier", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11156 + }, + { + "length": 32, + "start": 11965 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferVerifierLib.json b/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferVerifierLib.json new file mode 100644 index 0000000..b1151dc --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/transferExternalVerifier#TransferVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifier.json b/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifier.json new file mode 100644 index 0000000..bc84c2e --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "TransferVerifier", + "sourceName": "contracts/verifiers/TransferVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$8ca614531f81a5db991ca8a5216cacce22$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$8ca614531f81a5db991ca8a5216cacce22$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/TransferVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/TransferVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11154 + }, + { + "length": 32, + "start": 11963 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/TransferVerifier.sol", + "buildInfoId": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifierLib.json b/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifierLib.json new file mode 100644 index 0000000..1e0d5dd --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/transferVerifier#TransferVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/TransferVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/TransferVerifier.sol", + "buildInfoId": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifier.json b/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifier.json new file mode 100644 index 0000000..c3e97cf --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "WithdrawVerifier", + "sourceName": "contracts/verifiers/WithdrawVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$a55f4d19f769a9aa79c8ec5350ab3a0ed5$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$a55f4d19f769a9aa79c8ec5350ab3a0ed5$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11154 + }, + { + "length": 32, + "start": 11963 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/WithdrawVerifier.sol", + "buildInfoId": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifierLib.json b/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifierLib.json new file mode 100644 index 0000000..22f72f6 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/artifacts/withdrawVerifier#WithdrawVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/WithdrawVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/WithdrawVerifier.sol", + "buildInfoId": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json new file mode 100644 index 0000000..b82789e --- /dev/null +++ b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/WithdrawVerifier.sol": "project/contracts/verifiers/WithdrawVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 4096;\nuint256 constant LOG_N = 12;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 32;\nuint256 constant VK_HASH = 0x12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(4096),\n logCircuitSize: uint256(12),\n publicInputsSize: uint256(32),\n ql: Honk.G1Point({ \n x: uint256(0x29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b3),\n y: uint256(0x074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d337)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf2),\n y: uint256(0x0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b8),\n y: uint256(0x2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b),\n y: uint256(0x058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d8),\n y: uint256(0x062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d),\n y: uint256(0x08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c08),\n y: uint256(0x2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf8),\n y: uint256(0x07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a4),\n y: uint256(0x05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c7),\n y: uint256(0x283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda),\n y: uint256(0x0005c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d6),\n y: uint256(0x193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c),\n y: uint256(0x158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f3),\n y: uint256(0x00ce217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba1)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca),\n y: uint256(0x22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca119)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b38),\n y: uint256(0x0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d),\n y: uint256(0x041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba2)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee),\n y: uint256(0x2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f8),\n y: uint256(0x2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f20),\n y: uint256(0x0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da019),\n y: uint256(0x13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe),\n y: uint256(0x1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba23)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e),\n y: uint256(0x04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract WithdrawVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json new file mode 100644 index 0000000..d0b011a --- /dev/null +++ b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/DepositVerifier.sol": "project/contracts/verifiers/DepositVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/DepositVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 256;\nuint256 constant LOG_N = 8;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 19;\nuint256 constant VK_HASH = 0x0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(256),\n logCircuitSize: uint256(8),\n publicInputsSize: uint256(19),\n ql: Honk.G1Point({ \n x: uint256(0x149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d55),\n y: uint256(0x0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d1)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f30174),\n y: uint256(0x29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e98)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d),\n y: uint256(0x21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad6)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c61),\n y: uint256(0x01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d3)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b),\n y: uint256(0x2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf14),\n y: uint256(0x05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0073e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b0),\n y: uint256(0x20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c036),\n y: uint256(0x02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e4)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e),\n y: uint256(0x04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af),\n y: uint256(0x1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be88),\n y: uint256(0x1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f79),\n y: uint256(0x05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c253),\n y: uint256(0x0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e5),\n y: uint256(0x050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d190)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e),\n y: uint256(0x2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d981)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc98887),\n y: uint256(0x1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec235625)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef),\n y: uint256(0x0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c4982)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf),\n y: uint256(0x1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da2)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac),\n y: uint256(0x0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f),\n y: uint256(0x198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a),\n y: uint256(0x0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a),\n y: uint256(0x22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b1),\n y: uint256(0x2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract DepositVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json new file mode 100644 index 0000000..0d287cc --- /dev/null +++ b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/TransferVerifier.sol": "project/contracts/verifiers/TransferVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/TransferVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 16384;\nuint256 constant LOG_N = 14;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 23;\nuint256 constant VK_HASH = 0x1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(16384),\n logCircuitSize: uint256(14),\n publicInputsSize: uint256(23),\n ql: Honk.G1Point({ \n x: uint256(0x145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca),\n y: uint256(0x06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x0040a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b),\n y: uint256(0x165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f69),\n y: uint256(0x2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be),\n y: uint256(0x1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc),\n y: uint256(0x050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d),\n y: uint256(0x2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a991),\n y: uint256(0x286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df923)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e791),\n y: uint256(0x1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d4),\n y: uint256(0x035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb6)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c66),\n y: uint256(0x0037adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c3),\n y: uint256(0x175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f71),\n y: uint256(0x03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d6),\n y: uint256(0x20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a),\n y: uint256(0x19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a8)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af6),\n y: uint256(0x080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e),\n y: uint256(0x3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f048)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf),\n y: uint256(0x0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df313)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b),\n y: uint256(0x1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea2785)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f),\n y: uint256(0x0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d),\n y: uint256(0x04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf65),\n y: uint256(0x26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d9),\n y: uint256(0x18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f9),\n y: uint256(0x26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract TransferVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json new file mode 100644 index 0000000..a73304c --- /dev/null +++ b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/TransferExternalVerifier.sol": "project/contracts/verifiers/TransferExternalVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 16384;\nuint256 constant LOG_N = 14;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 35;\nuint256 constant VK_HASH = 0x0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a2988;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(16384),\n logCircuitSize: uint256(14),\n publicInputsSize: uint256(35),\n ql: Honk.G1Point({ \n x: uint256(0x282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db746),\n y: uint256(0x0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb746656)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a),\n y: uint256(0x147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b2),\n y: uint256(0x15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d),\n y: uint256(0x207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d9),\n y: uint256(0x2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb),\n y: uint256(0x1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf0),\n y: uint256(0x299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb23),\n y: uint256(0x0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a349160)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a),\n y: uint256(0x0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d95)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca),\n y: uint256(0x16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d),\n y: uint256(0x187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f46)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f112),\n y: uint256(0x30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b43),\n y: uint256(0x26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a),\n y: uint256(0x1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f824)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa),\n y: uint256(0x27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a3),\n y: uint256(0x049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c170773895124),\n y: uint256(0x01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c86)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d03),\n y: uint256(0x20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba665792934)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c76),\n y: uint256(0x035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e),\n y: uint256(0x25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c88),\n y: uint256(0x2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f581),\n y: uint256(0x0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e9)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d),\n y: uint256(0x1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract TransferExternalVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-09da3b80d3933002842fb02fea1acd238a2be744.json b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json similarity index 92% rename from contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-09da3b80d3933002842fb02fea1acd238a2be744.json rename to contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json index ed8d1b0..52c13ac 100644 --- a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-09da3b80d3933002842fb02fea1acd238a2be744.json +++ b/contracts/ignition/deployments/chain-1/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json @@ -1,6 +1,6 @@ { "_format": "hh3-sol-build-info-1", - "id": "solc-0_8_28-09da3b80d3933002842fb02fea1acd238a2be744", + "id": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838", "solcVersion": "0.8.28", "solcLongVersion": "0.8.28+commit.7893614a", "userSourceNameMap": { @@ -16,9 +16,7 @@ }, "outputSelection": { "*": { - "": [ - "ast" - ], + "": ["ast"], "*": [ "abi", "evm.bytecode", @@ -53,7 +51,7 @@ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" }, "project/contracts/CommBankDotEth.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\n// ___. __ __ .__\n// ____ ____ _____ _____\\_ |__ _____ ____ | | __ _____/ |_| |__\n// _/ ___\\/ _ \\ / \\ / \\| __ \\\\__ \\ / \\| |/ / _/ __ \\ __\\ | \\\n// \\ \\__( <_> ) Y Y \\ Y Y \\ \\_\\ \\/ __ \\| | \\ < \\ ___/| | | Y \\\n// \\___ >____/|__|_| /__|_| /___ (____ /___| /__|_ \\ /\\ \\___ >__| |___| /\n// \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/\n//\n// author: benhooper.eth\n\nimport \"./PoseidonMerkleTree.sol\";\n\nimport {IVerifier} from \"./verifiers/DepositVerifier.sol\";\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\ncontract CommBankDotEth is PoseidonMerkleTree, AccessControl {\n address public depositVerifier;\n address public transferVerifier;\n address public withdrawVerifier;\n\n mapping(bytes32 => bool) public nullifierUsed;\n\n bytes32 public DEPOSIT_ROLE = keccak256(\"DEPOSIT_ROLE\");\n\n event NullifierUsed(bytes32 indexed nullifier);\n event NotePayload(bytes encryptedNote);\n\n uint256 constant NOTES_INPUT_LENGTH = 3;\n uint256 constant EXIT_ASSET_START_INDEX = 4;\n uint256 constant EXIT_AMOUNT_START_INDEX = 7;\n uint256 constant EXIT_ADDRESSES_START_INDEX = 10;\n\n address public immutable ETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n constructor(\n address _noteVerifier,\n address _transactVerifier,\n address _withdrawalVerifier\n ) PoseidonMerkleTree(12) {\n depositVerifier = _noteVerifier;\n transferVerifier = _transactVerifier;\n withdrawVerifier = _withdrawalVerifier;\n\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _grantRole(DEPOSIT_ROLE, msg.sender);\n }\n\n function deposit(\n address _erc20,\n uint256 _amount, // with decimals\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public onlyRole(DEPOSIT_ROLE) {\n bool depositTransfer = IERC20(_erc20).transferFrom(\n msg.sender,\n address(this),\n _amount\n );\n require(depositTransfer, \"failed to transfer deposit\");\n\n // VERIFY PROOF\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // CHECK INPUT ADDRESS AND AMOUNT MATCH PROOF INPUTS\n require(\n _erc20 == address(uint160(uint256(_publicInputs[1]))),\n \"ERC20 address mismatch\"\n );\n require(\n _amount == uint64(uint256(_publicInputs[2])),\n \"Address amount incorrect\"\n );\n\n // INSERT NOTE INTO TREE\n _insert(uint256(_publicInputs[0]));\n\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function depositNative(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public payable onlyRole(DEPOSIT_ROLE) {\n // VERIFY PROOF\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check that input address is 0xEee address\n require(\n ETH_ADDRESS == address(uint160(uint256(_publicInputs[1]))),\n \"Address mismatch\"\n );\n // check that msg.value matches amount in proof\n require(msg.value == uint64(uint256(_publicInputs[2])), \"Amount incorrect\");\n\n // Insert note into tree\n _insert(uint256(_publicInputs[0]));\n\n // Emit encrypted payloads\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function transfer(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer proof\");\n\n // if proof is valid, write nullifiers as spent\n for (uint256 i = 1; i < NOTES_INPUT_LENGTH + 1; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // and insert output note commitments\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // emit payload note parameters\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function withdraw(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs\n ) public {\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n bool isValidProof = IVerifier(withdrawVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid withdraw proof\");\n\n // Mark nullifiers as spent\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process withdrawals\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = EXIT_ASSET_START_INDEX + i;\n uint256 amountIndex = EXIT_AMOUNT_START_INDEX + i;\n uint256 addressIndex = EXIT_ADDRESSES_START_INDEX + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0) {\n if (exitAsset == ETH_ADDRESS) {\n // if it's eth, send the amount of eth to them\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n // Transfer tokens to the exit address\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n }\n}\n" + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\nimport \"./PoseidonMerkleTree.sol\";\nimport {IVerifier} from \"./verifiers/DepositVerifier.sol\";\n\n// ___. __ __ .__\n// ____ ____ _____ _____\\_ |__ _____ ____ | | __ _____/ |_| |__\n// _/ ___\\/ _ \\ / \\ / \\| __ \\\\__ \\ / \\| |/ / _/ __ \\ __\\ | \\\n// \\ \\__( <_> ) Y Y \\ Y Y \\ \\_\\ \\/ __ \\| | \\ < \\ ___/| | | Y \\\n// \\___ >____/|__|_| /__|_| /___ (____ /___| /__|_ \\ /\\ \\___ >__| |___| /\n// \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/\n//\ncontract CommBankDotEth is PoseidonMerkleTree, AccessControl {\n address public depositVerifier;\n address public transferVerifier;\n address public withdrawVerifier;\n address public transferExternalVerifier;\n\n mapping(bytes32 => bool) public nullifierUsed;\n\n bytes32 public DEPOSIT_ROLE = keccak256(\"DEPOSIT_ROLE\");\n\n event NullifierUsed(bytes32 indexed nullifier);\n event NotePayload(bytes encryptedNote);\n\n uint256 constant NOTES_INPUT_LENGTH = 3;\n uint256 constant EXIT_ASSET_START_INDEX = 4;\n uint256 constant EXIT_AMOUNT_START_INDEX = 7;\n uint256 constant EXIT_ADDRESSES_START_INDEX = 10;\n\n address public immutable ETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n constructor(\n address _noteVerifier,\n address _transactVerifier,\n address _withdrawalVerifier,\n address _transferExternalVerifier\n ) PoseidonMerkleTree(12) {\n depositVerifier = _noteVerifier;\n transferVerifier = _transactVerifier;\n withdrawVerifier = _withdrawalVerifier;\n transferExternalVerifier = _transferExternalVerifier;\n\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _grantRole(DEPOSIT_ROLE, msg.sender);\n }\n\n function deposit(\n address _erc20,\n uint256 _amount, // with decimals\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public onlyRole(DEPOSIT_ROLE) {\n bool depositTransfer = IERC20(_erc20).transferFrom(\n msg.sender,\n address(this),\n _amount\n );\n require(depositTransfer, \"failed to transfer deposit\");\n\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check input input asset address and amount match proof inputs\n require(\n _erc20 == address(uint160(uint256(_publicInputs[1]))),\n \"ERC20 address mismatch\"\n );\n require(\n _amount == uint64(uint256(_publicInputs[2])),\n \"Address amount incorrect\"\n );\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function depositNative(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public payable onlyRole(DEPOSIT_ROLE) {\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check that input address is 0xEee address\n require(\n ETH_ADDRESS == address(uint160(uint256(_publicInputs[1]))),\n \"Address mismatch\"\n );\n // check that msg.value matches amount in proof\n require(msg.value == uint64(uint256(_publicInputs[2])), \"Amount incorrect\");\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function transfer(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer proof\");\n\n // if proof is valid, write nullifiers as spent\n for (uint256 i = 1; i < NOTES_INPUT_LENGTH + 1; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // and insert output notes\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // emit payload note parameters\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function withdraw(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs\n ) public {\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n bool isValidProof = IVerifier(withdrawVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid withdraw proof\");\n\n // Mark nullifiers as spent\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process withdrawals\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = EXIT_ASSET_START_INDEX + i;\n uint256 amountIndex = EXIT_AMOUNT_START_INDEX + i;\n uint256 addressIndex = EXIT_ADDRESSES_START_INDEX + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0) {\n if (exitAsset == ETH_ADDRESS) {\n // if it's eth, send the amount of eth to them\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n // Transfer tokens to the exit address\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n }\n\n // transfer function that allows for arbitrary amounts of withdrawal (not just note based)\n function transferExternal(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferExternalVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer external proof\");\n\n // Mark nullifiers as spent (indices 1-3)\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n nullifierUsed[_publicInputs[i]] = true;\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process output notes (indices 4-6 are output_hashes)\n // Insert internal transfer notes into merkle tree\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // Process external withdrawals (indices 7-9: exit_assets, 10-12: exit_amounts, 13-15: exit_addresses)\n uint256 exitAssetStartIndex = 7;\n uint256 exitAmountStartIndex = exitAssetStartIndex + NOTES_INPUT_LENGTH;\n uint256 exitAddressStartIndex = exitAmountStartIndex + NOTES_INPUT_LENGTH;\n\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = exitAssetStartIndex + i;\n uint256 amountIndex = exitAmountStartIndex + i;\n uint256 addressIndex = exitAddressStartIndex + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0 && exitAddress != address(0)) {\n if (exitAsset == ETH_ADDRESS) {\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n\n // Emit payload note parameters for internal transfers\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n}\n" }, "project/contracts/PoseidonMerkleTree.sol": { "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\ncontract PoseidonMerkleTree {\n // The root of a poseidon2 merkle tree with height 12 and all leaf nodes filled with:\n // EMPTY_LEAF = keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n uint256 public constant INITIAL_ROOT =\n 0x124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f;\n\n // The maximum field element in BN254\n uint256 public constant PRIME =\n 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;\n\n // filledSubtrees and roots could be bytes32[size], but using mappings makes it cheaper because\n // it removes index range check on every interaction\n mapping(uint256 => uint256) public filledSubtrees;\n mapping(uint256 => uint256) public roots;\n\n uint256 public immutable height; // 12\n\n uint32 public constant ROOT_HISTORY_SIZE = 100;\n uint32 public currentRootIndex = 0;\n uint256 public nextIndex = 0;\n\n uint256 public MAX_LEAF_INDEX;\n\n address public poseidon2Hasher;\n address public deployer;\n\n constructor(uint256 _height) {\n height = _height;\n MAX_LEAF_INDEX = 2 ** (_height - 1);\n\n roots[0] = uint256(INITIAL_ROOT);\n\n deployer = msg.sender;\n }\n\n // TODO make this better\n function setPoseidon(address _hasher) public {\n require(poseidon2Hasher == address(0), \"Can't set it twice!\");\n require(msg.sender == deployer, \"only deployer can set poseidon\");\n poseidon2Hasher = _hasher;\n }\n\n function zeros(uint256 i) public pure returns (uint256) {\n if (i == 0) {\n // Base ZERO_VALUE: keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n return\n uint256(\n 0x1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478\n );\n } else if (i == 1) {\n return\n uint256(\n 0x2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105\n );\n } else if (i == 2) {\n return\n uint256(\n 0x237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445\n );\n } else if (i == 3) {\n return\n uint256(\n 0x0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c\n );\n } else if (i == 4) {\n return\n uint256(\n 0x0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3\n );\n } else if (i == 5) {\n return\n uint256(\n 0x235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd\n );\n } else if (i == 6) {\n return\n uint256(\n 0x1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264\n );\n } else if (i == 7) {\n return\n uint256(\n 0x09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976\n );\n } else if (i == 8) {\n return\n uint256(\n 0x2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18\n );\n } else if (i == 9) {\n return\n uint256(\n 0x0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f\n );\n } else if (i == 10) {\n return\n uint256(\n 0x181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b\n );\n } else {\n revert(\"Index out of bounds\");\n }\n }\n\n event LeafInserted(uint256 indexed leafIndex, bytes32 indexed leafValue);\n\n // Add a helper function to generate consistent keys\n function getStorageKey(\n uint256 level,\n uint256 index\n ) internal pure returns (uint256) {\n return (level << 32) | index; // Combine level and index into a single key\n }\n\n function _insert(uint256 _leaf) internal returns (uint256 index) {\n uint256 insertIndex = nextIndex;\n require(insertIndex != MAX_LEAF_INDEX, \"Tree Full\");\n\n uint256 currentIndex = insertIndex;\n uint256 currentHash = _leaf;\n\n // Store leaf at level 0\n filledSubtrees[getStorageKey(0, currentIndex)] = currentHash;\n\n for (uint256 i = 0; i < height - 1; i++) {\n bool isLeft = currentIndex % 2 == 0;\n uint256 siblingIndex = isLeft ? currentIndex + 1 : currentIndex - 1;\n\n // Get sibling value using consistent key generation\n uint256 siblingKey = getStorageKey(i, siblingIndex);\n uint256 sibling = filledSubtrees[siblingKey];\n if (sibling == 0) {\n sibling = zeros(i);\n }\n\n // Calculate parent hash based on position\n if (isLeft) {\n currentHash = hashLeftRight(currentHash, sibling);\n } else {\n currentHash = hashLeftRight(sibling, currentHash);\n }\n\n // Move up to parent level\n currentIndex = currentIndex / 2;\n\n // Store the computed hash for the next level using consistent key\n filledSubtrees[getStorageKey(i + 1, currentIndex)] = currentHash;\n }\n\n uint32 newRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\n currentRootIndex = newRootIndex;\n roots[newRootIndex] = currentHash;\n\n nextIndex = insertIndex + 1;\n emit LeafInserted(insertIndex, bytes32(_leaf));\n\n return insertIndex;\n }\n\n function hashLeftRight(\n uint256 _left,\n uint256 _right\n ) public view returns (uint256) {\n // Encode two uint256 values as calldata for Poseidon2Yul\n bytes memory callData = abi.encode(_left, _right);\n\n // Call the Poseidon2Yul fallback function\n (bool success, bytes memory result) = poseidon2Hasher.staticcall(callData);\n require(success, \"Poseidon2 hash failed\");\n\n // Decode the result as uint256\n return abi.decode(result, (uint256));\n }\n\n function isKnownRoot(uint256 _root) public view returns (bool) {\n if (_root == 0) {\n return false;\n }\n uint32 _currentRootIndex = currentRootIndex;\n uint32 i = _currentRootIndex;\n do {\n if (_root == roots[i]) {\n return true;\n }\n if (i == 0) {\n i = ROOT_HISTORY_SIZE;\n }\n i--;\n } while (i != _currentRootIndex);\n return false;\n }\n}\n" @@ -63,4 +61,4 @@ } } } -} \ No newline at end of file +} diff --git a/contracts/ignition/deployments/chain-1/deployed_addresses.json b/contracts/ignition/deployments/chain-1/deployed_addresses.json new file mode 100644 index 0000000..471dc3d --- /dev/null +++ b/contracts/ignition/deployments/chain-1/deployed_addresses.json @@ -0,0 +1,11 @@ +{ + "depositVerifier#DepositVerifierLib": "0xf90c7e5FbC840B381002279B555dc3e0290Da095", + "transferExternalVerifier#TransferVerifierLib": "0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51", + "transferVerifier#TransferVerifierLib": "0x9A0E3f3d11F7bA8B92faD4533043b5994615629d", + "withdrawVerifier#WithdrawVerifierLib": "0xc246Abca0566848759dA29c30Fc77DC4A9962919", + "depositVerifier#DepositVerifier": "0x840feC4Efbd4764edAA237E78757cE59CeA3Db26", + "transferExternalVerifier#TransferExternalVerifier": "0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815", + "transferVerifier#TransferVerifier": "0xd3090af4727886D9b51FA38AC001025796Dd5E14", + "withdrawVerifier#WithdrawVerifier": "0x287243bD7650643B691cED24dfE854964Df045A1", + "commbankDotEth#CommBankDotEth": "0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e" +} diff --git a/contracts/ignition/deployments/chain-1/journal.jsonl b/contracts/ignition/deployments/chain-1/journal.jsonl new file mode 100644 index 0000000..b9b82e9 --- /dev/null +++ b/contracts/ignition/deployments/chain-1/journal.jsonl @@ -0,0 +1,56 @@ + +{"chainId":1,"type":"DEPLOYMENT_INITIALIZE"} +{"artifactId":"depositVerifier#DepositVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/DepositVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":2,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":2,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"52235502"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x2cffcc2ffc6021b858ff8f508f03c33a92df8a97ea7522af7a70f2181cf0bc96"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferExternalVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":3,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":3,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"61080294"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x794729bba19f4740b79aa614994a6b82fbe670c8d04f7d2d08d0e3f4011d3853"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":4,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":4,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"57622922"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x96578a04149ee873ce89d31dd35fd6e9047d1f1a75c8bcdade8127b9e32f592b"},"type":"TRANSACTION_SEND"} +{"artifactId":"withdrawVerifier#WithdrawVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/WithdrawVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":5,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":5,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"61414570"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x6bd6adf9b94d18b7136224fb969a76735ee1b56c27a46c40ae07c4c5b3dc0737"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","hash":"0x2cffcc2ffc6021b858ff8f508f03c33a92df8a97ea7522af7a70f2181cf0bc96","networkInteractionId":1,"receipt":{"blockHash":"0x106e1e6fc5a4e391b392581c1eadda9aa35122a0fa82165da1c87098affe007e","blockNumber":24267534,"contractAddress":"0xf90c7e5FbC840B381002279B555dc3e0290Da095","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifierLib","result":{"address":"0xf90c7e5FbC840B381002279B555dc3e0290Da095","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","hash":"0x794729bba19f4740b79aa614994a6b82fbe670c8d04f7d2d08d0e3f4011d3853","networkInteractionId":1,"receipt":{"blockHash":"0xa6ef031119ffb05f3da358b234dcfe49030aa47d3df58e72750e61be07e86539","blockNumber":24267537,"contractAddress":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","result":{"address":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifierLib","hash":"0x96578a04149ee873ce89d31dd35fd6e9047d1f1a75c8bcdade8127b9e32f592b","networkInteractionId":1,"receipt":{"blockHash":"0x943e915c8144cdcd8ecd524aaadb272d37f6cee624d6f273fa7c6bd0fc587605","blockNumber":24267545,"contractAddress":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifierLib","result":{"address":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","hash":"0x6bd6adf9b94d18b7136224fb969a76735ee1b56c27a46c40ae07c4c5b3dc0737","networkInteractionId":1,"receipt":{"blockHash":"0xf4507cf0e94369bfb5a46303b20914fb910908de62580f192358fdccbf696bb6","blockNumber":24267546,"contractAddress":"0xc246Abca0566848759dA29c30Fc77DC4A9962919","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","result":{"address":"0xc246Abca0566848759dA29c30Fc77DC4A9962919","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"depositVerifier#DepositVerifier","constructorArgs":[],"contractName":"DepositVerifier","dependencies":["depositVerifier#DepositVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xf90c7e5FbC840B381002279B555dc3e0290Da095"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"depositVerifier#DepositVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073f90c7e5FbC840B381002279B555dc3e0290Da0959063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":6,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":6,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"63109430"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0xc281c44de96412779262e8a394c1524693718e5bca5daf17a040e3db4c77a7e7"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferExternalVerifier","constructorArgs":[],"contractName":"TransferExternalVerifier","dependencies":["transferExternalVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferExternalVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073D1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf519063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":7,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":7,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"58534818"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x0ff865f8da404e9777df7217bb8140b7b0b45091be2b69b50a25a2208e4c1f3c"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferVerifier#TransferVerifier","constructorArgs":[],"contractName":"TransferVerifier","dependencies":["transferVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferVerifier#TransferVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f90739A0E3f3d11F7bA8B92faD4533043b5994615629d9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":8,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":8,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"65423910"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0xa49ef3fb08e0914bcd7548fb5d3dee7203747947951b0ea2f72ddc30eb31ca69"},"type":"TRANSACTION_SEND"} +{"artifactId":"withdrawVerifier#WithdrawVerifier","constructorArgs":[],"contractName":"WithdrawVerifier","dependencies":["withdrawVerifier#WithdrawVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xc246Abca0566848759dA29c30Fc77DC4A9962919"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073c246Abca0566848759dA29c30Fc77DC4A99629199063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":9,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":9,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"66342624"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0x7716d544708d93a069e72ba827043c90383c9f5f34b4159ef60a095e2a2ec473"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifier","hash":"0xc281c44de96412779262e8a394c1524693718e5bca5daf17a040e3db4c77a7e7","networkInteractionId":1,"receipt":{"blockHash":"0xcd2cbe09bd5f53b36f301e7da60902fe0ab7d624ef7c016a75a3f58bdbac8273","blockNumber":24267553,"contractAddress":"0x840feC4Efbd4764edAA237E78757cE59CeA3Db26","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifier","result":{"address":"0x840feC4Efbd4764edAA237E78757cE59CeA3Db26","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","hash":"0x0ff865f8da404e9777df7217bb8140b7b0b45091be2b69b50a25a2208e4c1f3c","networkInteractionId":1,"receipt":{"blockHash":"0x6da304ec9e788ffce8a274df9d2b2ae241dc90249bda25f2b3b039b276f135d0","blockNumber":24267555,"contractAddress":"0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","result":{"address":"0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifier","hash":"0xa49ef3fb08e0914bcd7548fb5d3dee7203747947951b0ea2f72ddc30eb31ca69","networkInteractionId":1,"receipt":{"blockHash":"0x2f417edaee82d88b7a8f699d1aa71061a6101e488e2d86fd445f1ba9edf96b7a","blockNumber":24267556,"contractAddress":"0xd3090af4727886D9b51FA38AC001025796Dd5E14","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifier","result":{"address":"0xd3090af4727886D9b51FA38AC001025796Dd5E14","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifier","hash":"0x7716d544708d93a069e72ba827043c90383c9f5f34b4159ef60a095e2a2ec473","networkInteractionId":1,"receipt":{"blockHash":"0x9e3654f59e926e46d4b3da13d8d81e7e378166c3fa24eb5bfc7911d850a6780d","blockNumber":24267558,"contractAddress":"0x287243bD7650643B691cED24dfE854964Df045A1","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifier","result":{"address":"0x287243bD7650643B691cED24dfE854964Df045A1","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"commbankDotEth#CommBankDotEth","constructorArgs":["0x840feC4Efbd4764edAA237E78757cE59CeA3Db26","0xd3090af4727886D9b51FA38AC001025796Dd5E14","0x287243bD7650643B691cED24dfE854964Df045A1","0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815"],"contractName":"CommBankDotEth","dependencies":["depositVerifier#DepositVerifier","transferVerifier#TransferVerifier","withdrawVerifier#WithdrawVerifier","transferExternalVerifier#TransferExternalVerifier"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"commbankDotEth#CommBankDotEth","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteraction":{"data":"0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033000000000000000000000000840fec4efbd4764edaa237e78757ce59cea3db26000000000000000000000000d3090af4727886d9b51fa38ac001025796dd5e14000000000000000000000000287243bd7650643b691ced24dfe854964df045a1000000000000000000000000237eeee66266c72dbb7ee2aa84811666ce4eb815","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":10,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":10,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"66971666"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"2"}},"hash":"0xebd9ea3898fd2b718e88c246c961cf60e2ad2f858d75e03ffa96bb9e6f72318b"},"type":"TRANSACTION_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","hash":"0xebd9ea3898fd2b718e88c246c961cf60e2ad2f858d75e03ffa96bb9e6f72318b","networkInteractionId":1,"receipt":{"blockHash":"0x3eafa0692486ac23238c839dca2fd89f63d75fe62378d0830dee190903cc2904","blockNumber":24267563,"contractAddress":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","logs":[{"address":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","data":"0x","logIndex":468,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]},{"address":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","data":"0x","logIndex":469,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"commbankDotEth#CommBankDotEth","result":{"address":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-11155111/artifacts/commbankDotEth#CommBankDotEth.json b/contracts/ignition/deployments/chain-11155111/artifacts/commbankDotEth#CommBankDotEth.json index 6226070..d2ad067 100644 --- a/contracts/ignition/deployments/chain-11155111/artifacts/commbankDotEth#CommBankDotEth.json +++ b/contracts/ignition/deployments/chain-11155111/artifacts/commbankDotEth#CommBankDotEth.json @@ -19,6 +19,11 @@ "internalType": "address", "name": "_withdrawalVerifier", "type": "address" + }, + { + "internalType": "address", + "name": "_transferExternalVerifier", + "type": "address" } ], "stateMutability": "nonpayable", @@ -642,6 +647,42 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "transferExternal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferExternalVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "transferVerifier", @@ -706,36 +747,40 @@ "type": "function" } ], - "bytecode": "0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600c5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b5060405161256538038061256583398101604081905261007b91610218565b600c608081905261008d60018261026c565b610098906002610362565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0388811691909117909155600980548316878316179055600a80549092169085161790556101399190610150565b50600c546101479033610150565b50505050610374565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff166101f4575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101ac3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016101f7565b505f5b92915050565b80516001600160a01b0381168114610213575f5ffd5b919050565b5f5f5f6060848603121561022a575f5ffd5b610233846101fd565b9250610241602085016101fd565b915061024f604085016101fd565b90509250925092565b634e487b7160e01b5f52601160045260245ffd5b818103818111156101f7576101f7610258565b6001815b60018411156102ba5780850481111561029e5761029e610258565b60018416156102ac57908102905b60019390931c928002610283565b935093915050565b5f826102d0575060016101f7565b816102dc57505f6101f7565b81600181146102f257600281146102fc57610318565b60019150506101f7565b60ff84111561030d5761030d610258565b50506001821b6101f7565b5060208310610133831016604e8410600b841016171561033b575081810a6101f7565b6103475f19848461027f565b805f190482111561035a5761035a610258565b029392505050565b5f61036d83836102c2565b9392505050565b60805160a0516121bb6103aa5f395f81816104b301528181610b1701526114a101525f81816102280152611a0001526121bb5ff3fe60806040526004361061019e575f3560e01c80638daed528116100df578063c2b40ae411610083578063c2b40ae414610527578063c46165b514610552578063cd87a3b414610565578063d547741f14610579578063d5f3948814610598578063e8295588146105b7578063f178e47c146105d6578063fc7e9c6f14610601575f5ffd5b80638daed5281461040157806390eeb02b1461042057806391d1485414610451578063a217fddf14610470578063a6232a9314610483578063a734f06e146104a2578063aa77c44a146104d5578063b42147cd146104f4575f5ffd5b806336568abe1161014657806336568abe146103045780635bb93995146103235780635e125d0d1461034257806367843a5b146103615780637ecf686d1461038057806380fc7498146103ae57806384746900146103c3578063864eb164146103e2575f5ffd5b806217cd8b146101a257806301ffc9a7146101e85780630ef26743146102175780631a702a241461024a578063248a9ca31461028157806326120c88146102af5780632f2ff15d146102ce578063353efdcf146102ef575b5f5ffd5b3480156101ad575f5ffd5b506101d57f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b3480156101f3575f5ffd5b50610207610202366004611bc4565b610616565b60405190151581526020016101df565b348015610222575f5ffd5b506101d57f000000000000000000000000000000000000000000000000000000000000000081565b348015610255575f5ffd5b50600554610269906001600160a01b031681565b6040516001600160a01b0390911681526020016101df565b34801561028c575f5ffd5b506101d561029b366004611bf2565b5f9081526007602052604090206001015490565b3480156102ba575f5ffd5b50600854610269906001600160a01b031681565b3480156102d9575f5ffd5b506102ed6102e8366004611c1f565b61064c565b005b3480156102fa575f5ffd5b506101d5600c5481565b34801561030f575f5ffd5b506102ed61031e366004611c1f565b610676565b34801561032e575f5ffd5b506101d561033d366004611c49565b6106ae565b34801561034d575f5ffd5b506102ed61035c366004611c69565b6107a6565b34801561036c575f5ffd5b506102ed61037b366004611d06565b610871565b34801561038b575f5ffd5b5061020761039a366004611bf2565b600b6020525f908152604090205460ff1681565b3480156103b9575f5ffd5b506101d560045481565b3480156103ce575f5ffd5b506102ed6103dd366004611d70565b610d0a565b3480156103ed575f5ffd5b50600a54610269906001600160a01b031681565b34801561040c575f5ffd5b50600954610269906001600160a01b031681565b34801561042b575f5ffd5b5060025461043c9063ffffffff1681565b60405163ffffffff90911681526020016101df565b34801561045c575f5ffd5b5061020761046b366004611c1f565b61102d565b34801561047b575f5ffd5b506101d55f81565b34801561048e575f5ffd5b5061020761049d366004611bf2565b611057565b3480156104ad575f5ffd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e0575f5ffd5b506102ed6104ef366004611e0c565b6110d0565b3480156104ff575f5ffd5b506101d57f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610532575f5ffd5b506101d5610541366004611bf2565b60016020525f908152604090205481565b6102ed610560366004611d70565b6113d9565b348015610570575f5ffd5b5061043c606481565b348015610584575f5ffd5b506102ed610593366004611c1f565b61162c565b3480156105a3575f5ffd5b50600654610269906001600160a01b031681565b3480156105c2575f5ffd5b506101d56105d1366004611bf2565b611650565b3480156105e1575f5ffd5b506101d56105f0366004611bf2565b5f6020819052908152604090205481565b34801561060c575f5ffd5b506101d560035481565b5f6001600160e01b03198216637965db0b60e01b148061064657506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f8281526007602052604090206001015461066681611898565b61067083836118a5565b50505050565b6001600160a01b038116331461069f5760405163334bd91960e11b815260040160405180910390fd5b6106a98282611936565b505050565b5f5f83836040516020016106cc929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906106fc908590611ec1565b5f60405180830381855afa9150503d805f8114610734576040519150601f19603f3d011682016040523d82523d5f602084013e610739565b606091505b5091509150816107885760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b8080602001905181019061079c9190611ed7565b9695505050505050565b6005546001600160a01b0316156107f55760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b604482015260640161077f565b6006546001600160a01b0316331461084f5760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e0000604482015260640161077f565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b61089482825f81811061088657610886611eee565b905060200201355f1c611057565b6108b05760405162461bcd60e51b815260040161077f90611f02565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906108e6908890889088908890600401611f51565b6020604051808303815f875af1158015610902573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109269190611f9b565b90508061096e5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604482015260640161077f565b60015b60038111610a7f575f84848381811061098c5761098c611eee565b9050602002013514610a6d57600b5f8585848181106109ad576109ad611eee565b602090810292909201358352508101919091526040015f205460ff16156109e65760405162461bcd60e51b815260040161077f90611fba565b6001600b5f8686858181106109fd576109fd611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a3957610a39611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b80610a7781611fff565b915050610971565b505f5b6003811015610d02575f610a97826004612017565b90505f610aa5836007612017565b90505f610ab384600a612017565b90505f878785818110610ac857610ac8611eee565b905060200201355f1c90505f888885818110610ae657610ae6611eee565b905060200201355f1c90505f898985818110610b0457610b04611eee565b60200291909101359150508115610cf0577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c345781471015610b995760405162461bcd60e51b8152602060048201526018602482015277496e73756666696369656e74204554482062616c616e636560401b604482015260640161077f565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610be2576040519150601f19603f3d011682016040523d82523d5f602084013e610be7565b606091505b5050905080610c2e5760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161077f565b50610cf0565b60405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490525f919085169063a9059cbb906044016020604051808303815f875af1158015610c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca79190611f9b565b905080610cee5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604482015260640161077f565b505b505060019094019350610a8292505050565b505050505050565b610d1f84845f81811061088657610886611eee565b610d3b5760405162461bcd60e51b815260040161077f90611f02565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d71908a908a908a908a90600401611f51565b6020604051808303815f875af1158015610d8d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db19190611f9b565b905080610df95760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b604482015260640161077f565b60015b610e0860036001612017565b811015610f0b575f868683818110610e2257610e22611eee565b9050602002013514610f0357600b5f878784818110610e4357610e43611eee565b602090810292909201358352508101919091526040015f205460ff1615610e7c5760405162461bcd60e51b815260040161077f90611fba565b6001600b5f888885818110610e9357610e93611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610ecf57610ecf611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b600101610dfc565b505f610f1960036001612017565b90505b6003610f29816001612017565b610f339190612017565b811015610f86575f868683818110610f4d57610f4d611eee565b9050602002013514610f7e57610f7c868683818110610f6e57610f6e611eee565b905060200201355f1c6119a1565b505b600101610f1c565b505f5b600381108015610f9857508281105b1561102357838382818110610faf57610faf611eee565b9050602002810190610fc1919061202a565b159050611011575f5160206121665f395f51905f52848483818110610fe857610fe8611eee565b9050602002810190610ffa919061202a565b60405161100892919061206c565b60405180910390a15b8061101b81611fff565b915050610f89565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361106657505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611096575060019392505050565b8063ffffffff165f036110a7575060645b806110b181612087565b9150508163ffffffff168163ffffffff160361107157505f9392505050565b600c546110dc81611898565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af115801561112e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111529190611f9b565b9050806111a15760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f736974000000000000604482015260640161077f565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906111d7908c908c908c908c90600401611f51565b6020604051808303815f875af11580156111f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112179190611f9b565b9050806112365760405162461bcd60e51b815260040161077f906120a5565b8686600181811061124957611249611eee565b905060200201355f1c6001600160a01b03168b6001600160a01b0316146112ab5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b604482015260640161077f565b868660028181106112be576112be611eee565b905060200201355f1c6001600160401b03168a146113195760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b604482015260640161077f565b61132e87875f818110610f6e57610f6e611eee565b505f5b60038110801561134057508481105b156113cb5785858281811061135757611357611eee565b9050602002810190611369919061202a565b1590506113b9575f5160206121665f395f51905f5286868381811061139057611390611eee565b90506020028101906113a2919061202a565b6040516113b092919061206c565b60405180910390a15b806113c381611fff565b915050611331565b505050505050505050505050565b600c546113e581611898565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061141b908b908b908b908b90600401611f51565b6020604051808303815f875af1158015611437573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145b9190611f9b565b90508061147a5760405162461bcd60e51b815260040161077f906120a5565b8585600181811061148d5761148d611eee565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146115095760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b604482015260640161077f565b8585600281811061151c5761151c611eee565b905060200201355f1c6001600160401b0316341461156f5760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b604482015260640161077f565b61158486865f818110610f6e57610f6e611eee565b505f5b60038110801561159657508381105b15611621578484828181106115ad576115ad611eee565b90506020028101906115bf919061202a565b15905061160f575f5160206121665f395f51905f528585838181106115e6576115e6611eee565b90506020028101906115f8919061202a565b60405161160692919061206c565b60405180910390a15b8061161981611fff565b915050611587565b505050505050505050565b5f8281526007602052604090206001015461164681611898565b6106708383611936565b5f815f0361167f57507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b816001036116ae57507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b816002036116dd57507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b8160030361170c57507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b8160040361173b57507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b8160050361176a57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b8160060361179957507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b816007036117c857507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b816008036117f757507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b8160090361182657507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a0361185557507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b604482015260640161077f565b919050565b6118a28133611b87565b50565b5f6118b0838361102d565b61192f575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556118e73390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610646565b505f610646565b5f611941838361102d565b1561192f575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610646565b6003546004545f919081036119e45760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b604482015260640161077f565b5f818152602081905260408120849055819084905b611a2460017f00000000000000000000000000000000000000000000000000000000000000006120d5565b811015611af1575f611a376002856120fc565b1590505f81611a5057611a4b6001866120d5565b611a5b565b611a5b856001612017565b602084811b82175f8181529182905260408220549293509190819003611a8757611a8485611650565b90505b8315611a9e57611a9786826106ae565b9550611aab565b611aa881876106ae565b95505b611ab660028861210f565b9650855f80611ad1611ac9896001612017565b60201b8b1790565b815260208101919091526040015f20555050600190920191506119f99050565b506002545f90606490611b0b9063ffffffff166001612122565b611b15919061213e565b6002805463ffffffff191663ffffffff83169081179091555f908152600160208190526040909120849055909150611b4e908590612017565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b611b91828261102d565b611bc05760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161077f565b5050565b5f60208284031215611bd4575f5ffd5b81356001600160e01b031981168114611beb575f5ffd5b9392505050565b5f60208284031215611c02575f5ffd5b5035919050565b80356001600160a01b0381168114611893575f5ffd5b5f5f60408385031215611c30575f5ffd5b82359150611c4060208401611c09565b90509250929050565b5f5f60408385031215611c5a575f5ffd5b50508035926020909101359150565b5f60208284031215611c79575f5ffd5b611beb82611c09565b5f5f83601f840112611c92575f5ffd5b5081356001600160401b03811115611ca8575f5ffd5b602083019150836020828501011115611cbf575f5ffd5b9250929050565b5f5f83601f840112611cd6575f5ffd5b5081356001600160401b03811115611cec575f5ffd5b6020830191508360208260051b8501011115611cbf575f5ffd5b5f5f5f5f60408587031215611d19575f5ffd5b84356001600160401b03811115611d2e575f5ffd5b611d3a87828801611c82565b90955093505060208501356001600160401b03811115611d58575f5ffd5b611d6487828801611cc6565b95989497509550505050565b5f5f5f5f5f5f60608789031215611d85575f5ffd5b86356001600160401b03811115611d9a575f5ffd5b611da689828a01611c82565b90975095505060208701356001600160401b03811115611dc4575f5ffd5b611dd089828a01611cc6565b90955093505060408701356001600160401b03811115611dee575f5ffd5b611dfa89828a01611cc6565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b031215611e23575f5ffd5b611e2c89611c09565b97506020890135965060408901356001600160401b03811115611e4d575f5ffd5b611e598b828c01611c82565b90975095505060608901356001600160401b03811115611e77575f5ffd5b611e838b828c01611cc6565b90955093505060808901356001600160401b03811115611ea1575f5ffd5b611ead8b828c01611cc6565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611ee7575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f611f64604083018688611f29565b82810360208401528381526001600160fb1b03841115611f82575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215611fab575f5ffd5b81518015158114611beb575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161201057612010611feb565b5060010190565b8082018082111561064657610646611feb565b5f5f8335601e1984360301811261203f575f5ffd5b8301803591506001600160401b03821115612058575f5ffd5b602001915036819003821315611cbf575f5ffd5b602081525f61207f602083018486611f29565b949350505050565b5f63ffffffff82168061209c5761209c611feb565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561064657610646611feb565b634e487b7160e01b5f52601260045260245ffd5b5f8261210a5761210a6120e8565b500690565b5f8261211d5761211d6120e8565b500490565b63ffffffff818116838216019081111561064657610646611feb565b5f63ffffffff831680612153576121536120e8565b8063ffffffff8416069150509291505056fe1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a2646970667358221220e72906da9e01e129b73110391184b6af4deda5d0bbed1a05cbfb6d409dffbda164736f6c634300081c0033", - "deployedBytecode": "0x60806040526004361061019e575f3560e01c80638daed528116100df578063c2b40ae411610083578063c2b40ae414610527578063c46165b514610552578063cd87a3b414610565578063d547741f14610579578063d5f3948814610598578063e8295588146105b7578063f178e47c146105d6578063fc7e9c6f14610601575f5ffd5b80638daed5281461040157806390eeb02b1461042057806391d1485414610451578063a217fddf14610470578063a6232a9314610483578063a734f06e146104a2578063aa77c44a146104d5578063b42147cd146104f4575f5ffd5b806336568abe1161014657806336568abe146103045780635bb93995146103235780635e125d0d1461034257806367843a5b146103615780637ecf686d1461038057806380fc7498146103ae57806384746900146103c3578063864eb164146103e2575f5ffd5b806217cd8b146101a257806301ffc9a7146101e85780630ef26743146102175780631a702a241461024a578063248a9ca31461028157806326120c88146102af5780632f2ff15d146102ce578063353efdcf146102ef575b5f5ffd5b3480156101ad575f5ffd5b506101d57f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b3480156101f3575f5ffd5b50610207610202366004611bc4565b610616565b60405190151581526020016101df565b348015610222575f5ffd5b506101d57f000000000000000000000000000000000000000000000000000000000000000081565b348015610255575f5ffd5b50600554610269906001600160a01b031681565b6040516001600160a01b0390911681526020016101df565b34801561028c575f5ffd5b506101d561029b366004611bf2565b5f9081526007602052604090206001015490565b3480156102ba575f5ffd5b50600854610269906001600160a01b031681565b3480156102d9575f5ffd5b506102ed6102e8366004611c1f565b61064c565b005b3480156102fa575f5ffd5b506101d5600c5481565b34801561030f575f5ffd5b506102ed61031e366004611c1f565b610676565b34801561032e575f5ffd5b506101d561033d366004611c49565b6106ae565b34801561034d575f5ffd5b506102ed61035c366004611c69565b6107a6565b34801561036c575f5ffd5b506102ed61037b366004611d06565b610871565b34801561038b575f5ffd5b5061020761039a366004611bf2565b600b6020525f908152604090205460ff1681565b3480156103b9575f5ffd5b506101d560045481565b3480156103ce575f5ffd5b506102ed6103dd366004611d70565b610d0a565b3480156103ed575f5ffd5b50600a54610269906001600160a01b031681565b34801561040c575f5ffd5b50600954610269906001600160a01b031681565b34801561042b575f5ffd5b5060025461043c9063ffffffff1681565b60405163ffffffff90911681526020016101df565b34801561045c575f5ffd5b5061020761046b366004611c1f565b61102d565b34801561047b575f5ffd5b506101d55f81565b34801561048e575f5ffd5b5061020761049d366004611bf2565b611057565b3480156104ad575f5ffd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e0575f5ffd5b506102ed6104ef366004611e0c565b6110d0565b3480156104ff575f5ffd5b506101d57f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610532575f5ffd5b506101d5610541366004611bf2565b60016020525f908152604090205481565b6102ed610560366004611d70565b6113d9565b348015610570575f5ffd5b5061043c606481565b348015610584575f5ffd5b506102ed610593366004611c1f565b61162c565b3480156105a3575f5ffd5b50600654610269906001600160a01b031681565b3480156105c2575f5ffd5b506101d56105d1366004611bf2565b611650565b3480156105e1575f5ffd5b506101d56105f0366004611bf2565b5f6020819052908152604090205481565b34801561060c575f5ffd5b506101d560035481565b5f6001600160e01b03198216637965db0b60e01b148061064657506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f8281526007602052604090206001015461066681611898565b61067083836118a5565b50505050565b6001600160a01b038116331461069f5760405163334bd91960e11b815260040160405180910390fd5b6106a98282611936565b505050565b5f5f83836040516020016106cc929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906106fc908590611ec1565b5f60405180830381855afa9150503d805f8114610734576040519150601f19603f3d011682016040523d82523d5f602084013e610739565b606091505b5091509150816107885760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b8080602001905181019061079c9190611ed7565b9695505050505050565b6005546001600160a01b0316156107f55760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b604482015260640161077f565b6006546001600160a01b0316331461084f5760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e0000604482015260640161077f565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b61089482825f81811061088657610886611eee565b905060200201355f1c611057565b6108b05760405162461bcd60e51b815260040161077f90611f02565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906108e6908890889088908890600401611f51565b6020604051808303815f875af1158015610902573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109269190611f9b565b90508061096e5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604482015260640161077f565b60015b60038111610a7f575f84848381811061098c5761098c611eee565b9050602002013514610a6d57600b5f8585848181106109ad576109ad611eee565b602090810292909201358352508101919091526040015f205460ff16156109e65760405162461bcd60e51b815260040161077f90611fba565b6001600b5f8686858181106109fd576109fd611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a3957610a39611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b80610a7781611fff565b915050610971565b505f5b6003811015610d02575f610a97826004612017565b90505f610aa5836007612017565b90505f610ab384600a612017565b90505f878785818110610ac857610ac8611eee565b905060200201355f1c90505f888885818110610ae657610ae6611eee565b905060200201355f1c90505f898985818110610b0457610b04611eee565b60200291909101359150508115610cf0577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c345781471015610b995760405162461bcd60e51b8152602060048201526018602482015277496e73756666696369656e74204554482062616c616e636560401b604482015260640161077f565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610be2576040519150601f19603f3d011682016040523d82523d5f602084013e610be7565b606091505b5050905080610c2e5760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161077f565b50610cf0565b60405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490525f919085169063a9059cbb906044016020604051808303815f875af1158015610c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca79190611f9b565b905080610cee5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604482015260640161077f565b505b505060019094019350610a8292505050565b505050505050565b610d1f84845f81811061088657610886611eee565b610d3b5760405162461bcd60e51b815260040161077f90611f02565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d71908a908a908a908a90600401611f51565b6020604051808303815f875af1158015610d8d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db19190611f9b565b905080610df95760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b604482015260640161077f565b60015b610e0860036001612017565b811015610f0b575f868683818110610e2257610e22611eee565b9050602002013514610f0357600b5f878784818110610e4357610e43611eee565b602090810292909201358352508101919091526040015f205460ff1615610e7c5760405162461bcd60e51b815260040161077f90611fba565b6001600b5f888885818110610e9357610e93611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610ecf57610ecf611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b600101610dfc565b505f610f1960036001612017565b90505b6003610f29816001612017565b610f339190612017565b811015610f86575f868683818110610f4d57610f4d611eee565b9050602002013514610f7e57610f7c868683818110610f6e57610f6e611eee565b905060200201355f1c6119a1565b505b600101610f1c565b505f5b600381108015610f9857508281105b1561102357838382818110610faf57610faf611eee565b9050602002810190610fc1919061202a565b159050611011575f5160206121665f395f51905f52848483818110610fe857610fe8611eee565b9050602002810190610ffa919061202a565b60405161100892919061206c565b60405180910390a15b8061101b81611fff565b915050610f89565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361106657505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611096575060019392505050565b8063ffffffff165f036110a7575060645b806110b181612087565b9150508163ffffffff168163ffffffff160361107157505f9392505050565b600c546110dc81611898565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af115801561112e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111529190611f9b565b9050806111a15760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f736974000000000000604482015260640161077f565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906111d7908c908c908c908c90600401611f51565b6020604051808303815f875af11580156111f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112179190611f9b565b9050806112365760405162461bcd60e51b815260040161077f906120a5565b8686600181811061124957611249611eee565b905060200201355f1c6001600160a01b03168b6001600160a01b0316146112ab5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b604482015260640161077f565b868660028181106112be576112be611eee565b905060200201355f1c6001600160401b03168a146113195760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b604482015260640161077f565b61132e87875f818110610f6e57610f6e611eee565b505f5b60038110801561134057508481105b156113cb5785858281811061135757611357611eee565b9050602002810190611369919061202a565b1590506113b9575f5160206121665f395f51905f5286868381811061139057611390611eee565b90506020028101906113a2919061202a565b6040516113b092919061206c565b60405180910390a15b806113c381611fff565b915050611331565b505050505050505050505050565b600c546113e581611898565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061141b908b908b908b908b90600401611f51565b6020604051808303815f875af1158015611437573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145b9190611f9b565b90508061147a5760405162461bcd60e51b815260040161077f906120a5565b8585600181811061148d5761148d611eee565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146115095760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b604482015260640161077f565b8585600281811061151c5761151c611eee565b905060200201355f1c6001600160401b0316341461156f5760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b604482015260640161077f565b61158486865f818110610f6e57610f6e611eee565b505f5b60038110801561159657508381105b15611621578484828181106115ad576115ad611eee565b90506020028101906115bf919061202a565b15905061160f575f5160206121665f395f51905f528585838181106115e6576115e6611eee565b90506020028101906115f8919061202a565b60405161160692919061206c565b60405180910390a15b8061161981611fff565b915050611587565b505050505050505050565b5f8281526007602052604090206001015461164681611898565b6106708383611936565b5f815f0361167f57507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b816001036116ae57507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b816002036116dd57507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b8160030361170c57507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b8160040361173b57507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b8160050361176a57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b8160060361179957507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b816007036117c857507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b816008036117f757507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b8160090361182657507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a0361185557507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b604482015260640161077f565b919050565b6118a28133611b87565b50565b5f6118b0838361102d565b61192f575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556118e73390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610646565b505f610646565b5f611941838361102d565b1561192f575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610646565b6003546004545f919081036119e45760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b604482015260640161077f565b5f818152602081905260408120849055819084905b611a2460017f00000000000000000000000000000000000000000000000000000000000000006120d5565b811015611af1575f611a376002856120fc565b1590505f81611a5057611a4b6001866120d5565b611a5b565b611a5b856001612017565b602084811b82175f8181529182905260408220549293509190819003611a8757611a8485611650565b90505b8315611a9e57611a9786826106ae565b9550611aab565b611aa881876106ae565b95505b611ab660028861210f565b9650855f80611ad1611ac9896001612017565b60201b8b1790565b815260208101919091526040015f20555050600190920191506119f99050565b506002545f90606490611b0b9063ffffffff166001612122565b611b15919061213e565b6002805463ffffffff191663ffffffff83169081179091555f908152600160208190526040909120849055909150611b4e908590612017565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b611b91828261102d565b611bc05760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161077f565b5050565b5f60208284031215611bd4575f5ffd5b81356001600160e01b031981168114611beb575f5ffd5b9392505050565b5f60208284031215611c02575f5ffd5b5035919050565b80356001600160a01b0381168114611893575f5ffd5b5f5f60408385031215611c30575f5ffd5b82359150611c4060208401611c09565b90509250929050565b5f5f60408385031215611c5a575f5ffd5b50508035926020909101359150565b5f60208284031215611c79575f5ffd5b611beb82611c09565b5f5f83601f840112611c92575f5ffd5b5081356001600160401b03811115611ca8575f5ffd5b602083019150836020828501011115611cbf575f5ffd5b9250929050565b5f5f83601f840112611cd6575f5ffd5b5081356001600160401b03811115611cec575f5ffd5b6020830191508360208260051b8501011115611cbf575f5ffd5b5f5f5f5f60408587031215611d19575f5ffd5b84356001600160401b03811115611d2e575f5ffd5b611d3a87828801611c82565b90955093505060208501356001600160401b03811115611d58575f5ffd5b611d6487828801611cc6565b95989497509550505050565b5f5f5f5f5f5f60608789031215611d85575f5ffd5b86356001600160401b03811115611d9a575f5ffd5b611da689828a01611c82565b90975095505060208701356001600160401b03811115611dc4575f5ffd5b611dd089828a01611cc6565b90955093505060408701356001600160401b03811115611dee575f5ffd5b611dfa89828a01611cc6565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b031215611e23575f5ffd5b611e2c89611c09565b97506020890135965060408901356001600160401b03811115611e4d575f5ffd5b611e598b828c01611c82565b90975095505060608901356001600160401b03811115611e77575f5ffd5b611e838b828c01611cc6565b90955093505060808901356001600160401b03811115611ea1575f5ffd5b611ead8b828c01611cc6565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611ee7575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f611f64604083018688611f29565b82810360208401528381526001600160fb1b03841115611f82575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215611fab575f5ffd5b81518015158114611beb575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161201057612010611feb565b5060010190565b8082018082111561064657610646611feb565b5f5f8335601e1984360301811261203f575f5ffd5b8301803591506001600160401b03821115612058575f5ffd5b602001915036819003821315611cbf575f5ffd5b602081525f61207f602083018486611f29565b949350505050565b5f63ffffffff82168061209c5761209c611feb565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561064657610646611feb565b634e487b7160e01b5f52601260045260245ffd5b5f8261210a5761210a6120e8565b500690565b5f8261211d5761211d6120e8565b500490565b63ffffffff818116838216019081111561064657610646611feb565b5f63ffffffff831680612153576121536120e8565b8063ffffffff8416069150509291505056fe1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a2646970667358221220e72906da9e01e129b73110391184b6af4deda5d0bbed1a05cbfb6d409dffbda164736f6c634300081c0033", + "bytecode": "0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", + "deployedBytecode": "0x6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "573": [ + "576": [ + { + "length": 32, + "start": 1225 + }, { "length": 32, - "start": 1203 + "start": 2904 }, { "length": 32, - "start": 2839 + "start": 5813 }, { "length": 32, - "start": 5281 + "start": 6550 } ], - "1219": [ + "1525": [ { "length": 32, - "start": 552 + "start": 574 }, { "length": 32, - "start": 6656 + "start": 7925 } ] }, "inputSourceName": "project/contracts/CommBankDotEth.sol", - "buildInfoId": "solc-0_8_28-09da3b80d3933002842fb02fea1acd238a2be744" + "buildInfoId": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838" } \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferExternalVerifier.json b/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferExternalVerifier.json new file mode 100644 index 0000000..f76e480 --- /dev/null +++ b/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferExternalVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "TransferExternalVerifier", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11156 + }, + { + "length": 32, + "start": 11965 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferVerifierLib.json b/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferVerifierLib.json new file mode 100644 index 0000000..b1151dc --- /dev/null +++ b/contracts/ignition/deployments/chain-11155111/artifacts/transferExternalVerifier#TransferVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json index cdd7940..b82789e 100644 --- a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json +++ b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json @@ -16,9 +16,7 @@ }, "outputSelection": { "*": { - "": [ - "ast" - ], + "": ["ast"], "*": [ "abi", "evm.bytecode", @@ -36,4 +34,4 @@ } } } -} \ No newline at end of file +} diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json index d725326..d0b011a 100644 --- a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json +++ b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json @@ -16,9 +16,7 @@ }, "outputSelection": { "*": { - "": [ - "ast" - ], + "": ["ast"], "*": [ "abi", "evm.bytecode", @@ -36,4 +34,4 @@ } } } -} \ No newline at end of file +} diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json index 28365ac..0d287cc 100644 --- a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json +++ b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json @@ -16,9 +16,7 @@ }, "outputSelection": { "*": { - "": [ - "ast" - ], + "": ["ast"], "*": [ "abi", "evm.bytecode", @@ -36,4 +34,4 @@ } } } -} \ No newline at end of file +} diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json new file mode 100644 index 0000000..a73304c --- /dev/null +++ b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/TransferExternalVerifier.sol": "project/contracts/verifiers/TransferExternalVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 16384;\nuint256 constant LOG_N = 14;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 35;\nuint256 constant VK_HASH = 0x0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a2988;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(16384),\n logCircuitSize: uint256(14),\n publicInputsSize: uint256(35),\n ql: Honk.G1Point({ \n x: uint256(0x282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db746),\n y: uint256(0x0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb746656)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a),\n y: uint256(0x147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b2),\n y: uint256(0x15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d),\n y: uint256(0x207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d9),\n y: uint256(0x2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb),\n y: uint256(0x1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf0),\n y: uint256(0x299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb23),\n y: uint256(0x0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a349160)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a),\n y: uint256(0x0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d95)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca),\n y: uint256(0x16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d),\n y: uint256(0x187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f46)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f112),\n y: uint256(0x30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b43),\n y: uint256(0x26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a),\n y: uint256(0x1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f824)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa),\n y: uint256(0x27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a3),\n y: uint256(0x049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c170773895124),\n y: uint256(0x01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c86)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d03),\n y: uint256(0x20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba665792934)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c76),\n y: uint256(0x035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e),\n y: uint256(0x25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c88),\n y: uint256(0x2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f581),\n y: uint256(0x0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e9)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d),\n y: uint256(0x1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract TransferExternalVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json new file mode 100644 index 0000000..52c13ac --- /dev/null +++ b/contracts/ignition/deployments/chain-11155111/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json @@ -0,0 +1,64 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/CommBankDotEth.sol": "project/contracts/CommBankDotEth.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [ + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/", + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" + ] + }, + "sources": { + "npm/@openzeppelin/contracts@5.4.0/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {IERC165, ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address account => bool) hasRole;\n bytes32 adminRole;\n }\n\n mapping(bytes32 role => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with an {AccessControlUnauthorizedAccount} error including the required role.\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n return _roles[role].hasRole[account];\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n * is missing `role`.\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert AccessControlUnauthorizedAccount(account, role);\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n if (callerConfirmation != _msgSender()) {\n revert AccessControlBadConfirmation();\n }\n\n _revokeRole(role, callerConfirmation);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n if (!hasRole(role, account)) {\n _roles[role].hasRole[account] = true;\n emit RoleGranted(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n if (hasRole(role, account)) {\n _roles[role].hasRole[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev The `account` is missing a role.\n */\n error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n /**\n * @dev The caller of a function is not the expected one.\n *\n * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n */\n error AccessControlBadConfirmation();\n\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted to signal this.\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n */\n function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "project/contracts/CommBankDotEth.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\nimport \"./PoseidonMerkleTree.sol\";\nimport {IVerifier} from \"./verifiers/DepositVerifier.sol\";\n\n// ___. __ __ .__\n// ____ ____ _____ _____\\_ |__ _____ ____ | | __ _____/ |_| |__\n// _/ ___\\/ _ \\ / \\ / \\| __ \\\\__ \\ / \\| |/ / _/ __ \\ __\\ | \\\n// \\ \\__( <_> ) Y Y \\ Y Y \\ \\_\\ \\/ __ \\| | \\ < \\ ___/| | | Y \\\n// \\___ >____/|__|_| /__|_| /___ (____ /___| /__|_ \\ /\\ \\___ >__| |___| /\n// \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/\n//\ncontract CommBankDotEth is PoseidonMerkleTree, AccessControl {\n address public depositVerifier;\n address public transferVerifier;\n address public withdrawVerifier;\n address public transferExternalVerifier;\n\n mapping(bytes32 => bool) public nullifierUsed;\n\n bytes32 public DEPOSIT_ROLE = keccak256(\"DEPOSIT_ROLE\");\n\n event NullifierUsed(bytes32 indexed nullifier);\n event NotePayload(bytes encryptedNote);\n\n uint256 constant NOTES_INPUT_LENGTH = 3;\n uint256 constant EXIT_ASSET_START_INDEX = 4;\n uint256 constant EXIT_AMOUNT_START_INDEX = 7;\n uint256 constant EXIT_ADDRESSES_START_INDEX = 10;\n\n address public immutable ETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n constructor(\n address _noteVerifier,\n address _transactVerifier,\n address _withdrawalVerifier,\n address _transferExternalVerifier\n ) PoseidonMerkleTree(12) {\n depositVerifier = _noteVerifier;\n transferVerifier = _transactVerifier;\n withdrawVerifier = _withdrawalVerifier;\n transferExternalVerifier = _transferExternalVerifier;\n\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _grantRole(DEPOSIT_ROLE, msg.sender);\n }\n\n function deposit(\n address _erc20,\n uint256 _amount, // with decimals\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public onlyRole(DEPOSIT_ROLE) {\n bool depositTransfer = IERC20(_erc20).transferFrom(\n msg.sender,\n address(this),\n _amount\n );\n require(depositTransfer, \"failed to transfer deposit\");\n\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check input input asset address and amount match proof inputs\n require(\n _erc20 == address(uint160(uint256(_publicInputs[1]))),\n \"ERC20 address mismatch\"\n );\n require(\n _amount == uint64(uint256(_publicInputs[2])),\n \"Address amount incorrect\"\n );\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function depositNative(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public payable onlyRole(DEPOSIT_ROLE) {\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check that input address is 0xEee address\n require(\n ETH_ADDRESS == address(uint160(uint256(_publicInputs[1]))),\n \"Address mismatch\"\n );\n // check that msg.value matches amount in proof\n require(msg.value == uint64(uint256(_publicInputs[2])), \"Amount incorrect\");\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function transfer(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer proof\");\n\n // if proof is valid, write nullifiers as spent\n for (uint256 i = 1; i < NOTES_INPUT_LENGTH + 1; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // and insert output notes\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // emit payload note parameters\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function withdraw(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs\n ) public {\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n bool isValidProof = IVerifier(withdrawVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid withdraw proof\");\n\n // Mark nullifiers as spent\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process withdrawals\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = EXIT_ASSET_START_INDEX + i;\n uint256 amountIndex = EXIT_AMOUNT_START_INDEX + i;\n uint256 addressIndex = EXIT_ADDRESSES_START_INDEX + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0) {\n if (exitAsset == ETH_ADDRESS) {\n // if it's eth, send the amount of eth to them\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n // Transfer tokens to the exit address\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n }\n\n // transfer function that allows for arbitrary amounts of withdrawal (not just note based)\n function transferExternal(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferExternalVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer external proof\");\n\n // Mark nullifiers as spent (indices 1-3)\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n nullifierUsed[_publicInputs[i]] = true;\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process output notes (indices 4-6 are output_hashes)\n // Insert internal transfer notes into merkle tree\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // Process external withdrawals (indices 7-9: exit_assets, 10-12: exit_amounts, 13-15: exit_addresses)\n uint256 exitAssetStartIndex = 7;\n uint256 exitAmountStartIndex = exitAssetStartIndex + NOTES_INPUT_LENGTH;\n uint256 exitAddressStartIndex = exitAmountStartIndex + NOTES_INPUT_LENGTH;\n\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = exitAssetStartIndex + i;\n uint256 amountIndex = exitAmountStartIndex + i;\n uint256 addressIndex = exitAddressStartIndex + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0 && exitAddress != address(0)) {\n if (exitAsset == ETH_ADDRESS) {\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n\n // Emit payload note parameters for internal transfers\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n}\n" + }, + "project/contracts/PoseidonMerkleTree.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\ncontract PoseidonMerkleTree {\n // The root of a poseidon2 merkle tree with height 12 and all leaf nodes filled with:\n // EMPTY_LEAF = keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n uint256 public constant INITIAL_ROOT =\n 0x124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f;\n\n // The maximum field element in BN254\n uint256 public constant PRIME =\n 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;\n\n // filledSubtrees and roots could be bytes32[size], but using mappings makes it cheaper because\n // it removes index range check on every interaction\n mapping(uint256 => uint256) public filledSubtrees;\n mapping(uint256 => uint256) public roots;\n\n uint256 public immutable height; // 12\n\n uint32 public constant ROOT_HISTORY_SIZE = 100;\n uint32 public currentRootIndex = 0;\n uint256 public nextIndex = 0;\n\n uint256 public MAX_LEAF_INDEX;\n\n address public poseidon2Hasher;\n address public deployer;\n\n constructor(uint256 _height) {\n height = _height;\n MAX_LEAF_INDEX = 2 ** (_height - 1);\n\n roots[0] = uint256(INITIAL_ROOT);\n\n deployer = msg.sender;\n }\n\n // TODO make this better\n function setPoseidon(address _hasher) public {\n require(poseidon2Hasher == address(0), \"Can't set it twice!\");\n require(msg.sender == deployer, \"only deployer can set poseidon\");\n poseidon2Hasher = _hasher;\n }\n\n function zeros(uint256 i) public pure returns (uint256) {\n if (i == 0) {\n // Base ZERO_VALUE: keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n return\n uint256(\n 0x1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478\n );\n } else if (i == 1) {\n return\n uint256(\n 0x2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105\n );\n } else if (i == 2) {\n return\n uint256(\n 0x237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445\n );\n } else if (i == 3) {\n return\n uint256(\n 0x0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c\n );\n } else if (i == 4) {\n return\n uint256(\n 0x0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3\n );\n } else if (i == 5) {\n return\n uint256(\n 0x235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd\n );\n } else if (i == 6) {\n return\n uint256(\n 0x1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264\n );\n } else if (i == 7) {\n return\n uint256(\n 0x09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976\n );\n } else if (i == 8) {\n return\n uint256(\n 0x2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18\n );\n } else if (i == 9) {\n return\n uint256(\n 0x0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f\n );\n } else if (i == 10) {\n return\n uint256(\n 0x181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b\n );\n } else {\n revert(\"Index out of bounds\");\n }\n }\n\n event LeafInserted(uint256 indexed leafIndex, bytes32 indexed leafValue);\n\n // Add a helper function to generate consistent keys\n function getStorageKey(\n uint256 level,\n uint256 index\n ) internal pure returns (uint256) {\n return (level << 32) | index; // Combine level and index into a single key\n }\n\n function _insert(uint256 _leaf) internal returns (uint256 index) {\n uint256 insertIndex = nextIndex;\n require(insertIndex != MAX_LEAF_INDEX, \"Tree Full\");\n\n uint256 currentIndex = insertIndex;\n uint256 currentHash = _leaf;\n\n // Store leaf at level 0\n filledSubtrees[getStorageKey(0, currentIndex)] = currentHash;\n\n for (uint256 i = 0; i < height - 1; i++) {\n bool isLeft = currentIndex % 2 == 0;\n uint256 siblingIndex = isLeft ? currentIndex + 1 : currentIndex - 1;\n\n // Get sibling value using consistent key generation\n uint256 siblingKey = getStorageKey(i, siblingIndex);\n uint256 sibling = filledSubtrees[siblingKey];\n if (sibling == 0) {\n sibling = zeros(i);\n }\n\n // Calculate parent hash based on position\n if (isLeft) {\n currentHash = hashLeftRight(currentHash, sibling);\n } else {\n currentHash = hashLeftRight(sibling, currentHash);\n }\n\n // Move up to parent level\n currentIndex = currentIndex / 2;\n\n // Store the computed hash for the next level using consistent key\n filledSubtrees[getStorageKey(i + 1, currentIndex)] = currentHash;\n }\n\n uint32 newRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\n currentRootIndex = newRootIndex;\n roots[newRootIndex] = currentHash;\n\n nextIndex = insertIndex + 1;\n emit LeafInserted(insertIndex, bytes32(_leaf));\n\n return insertIndex;\n }\n\n function hashLeftRight(\n uint256 _left,\n uint256 _right\n ) public view returns (uint256) {\n // Encode two uint256 values as calldata for Poseidon2Yul\n bytes memory callData = abi.encode(_left, _right);\n\n // Call the Poseidon2Yul fallback function\n (bool success, bytes memory result) = poseidon2Hasher.staticcall(callData);\n require(success, \"Poseidon2 hash failed\");\n\n // Decode the result as uint256\n return abi.decode(result, (uint256));\n }\n\n function isKnownRoot(uint256 _root) public view returns (bool) {\n if (_root == 0) {\n return false;\n }\n uint32 _currentRootIndex = currentRootIndex;\n uint32 i = _currentRootIndex;\n do {\n if (_root == roots[i]) {\n return true;\n }\n if (i == 0) {\n i = ROOT_HISTORY_SIZE;\n }\n i--;\n } while (i != _currentRootIndex);\n return false;\n }\n}\n" + }, + "project/contracts/verifiers/DepositVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 256;\nuint256 constant LOG_N = 8;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 19;\nuint256 constant VK_HASH = 0x0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(256),\n logCircuitSize: uint256(8),\n publicInputsSize: uint256(19),\n ql: Honk.G1Point({ \n x: uint256(0x149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d55),\n y: uint256(0x0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d1)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f30174),\n y: uint256(0x29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e98)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d),\n y: uint256(0x21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad6)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c61),\n y: uint256(0x01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d3)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b),\n y: uint256(0x2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf14),\n y: uint256(0x05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0073e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b0),\n y: uint256(0x20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c036),\n y: uint256(0x02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e4)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e),\n y: uint256(0x04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af),\n y: uint256(0x1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be88),\n y: uint256(0x1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f79),\n y: uint256(0x05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c253),\n y: uint256(0x0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e5),\n y: uint256(0x050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d190)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e),\n y: uint256(0x2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d981)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc98887),\n y: uint256(0x1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec235625)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef),\n y: uint256(0x0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c4982)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf),\n y: uint256(0x1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da2)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac),\n y: uint256(0x0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f),\n y: uint256(0x198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a),\n y: uint256(0x0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a),\n y: uint256(0x22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b1),\n y: uint256(0x2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract DepositVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-11155111/deployed_addresses.json b/contracts/ignition/deployments/chain-11155111/deployed_addresses.json index 828fd31..ff45133 100644 --- a/contracts/ignition/deployments/chain-11155111/deployed_addresses.json +++ b/contracts/ignition/deployments/chain-11155111/deployed_addresses.json @@ -1,12 +1,11 @@ { - "depositVerifier#DepositVerifierLib": "0x4AD5C3d68C5038AfE010EcF9d3041Aa068Da6D11", - "transferVerifier#TransferVerifierLib": "0xA7edA38ae0Ebb9150172A72Aed3c94e1b7b75369", - "withdrawVerifier#WithdrawVerifierLib": "0xeBfD88f112cC69c3cd02C846f4eAD8759B4aE7F3", - "depositVerifier#DepositVerifier": "0x44C4589Ceb6C358044014CC4120D02495b68C2F7", - "transferVerifier#TransferVerifier": "0x4875435f82a0B2abda43BF6E5fA2A66FEc25746B", - "withdrawVerifier#WithdrawVerifier": "0x05796fA1Df106917cbC82DDB3B3449CEDed43734", - "commbankDotEth#CommBankDotEth": "0x582E8C09955727112014B50A4eB3978697CDCB77", - "tokens#AUDD": "0xd794125Bc226895b987845Ef768B8C104fAbecD5", - "tokens#FourDEC": "0xbc4c167c1Ce11292CFb93FF8e9363d841d1ac97F", - "tokens#USDC": "0x49479Db3A172F9D5E190C994C5fB0B8d2099E1a9" + "depositVerifier#DepositVerifierLib": "0xEf3cB11Af34F9163ADb870074252dD49a484d664", + "transferExternalVerifier#TransferVerifierLib": "0x9070f3c785C901d4d825D5d28d1aeD4Ae4e49d3b", + "transferVerifier#TransferVerifierLib": "0x33528772d99Bf7afF96Db20321638664019CC40C", + "withdrawVerifier#WithdrawVerifierLib": "0x60b721B9b7c103cB010CfC1844ddD3c6eA5D4E47", + "depositVerifier#DepositVerifier": "0x9d29CfBF46c8779FB699fd4725651eA26dfb5678", + "transferExternalVerifier#TransferExternalVerifier": "0x77c4665654Af3822A35EB51cF1a42494C7a5047F", + "transferVerifier#TransferVerifier": "0xC4Bdd4CF56a974D8021e5c7Ad837Afa18ACbFf46", + "withdrawVerifier#WithdrawVerifier": "0xae59070836A08C4F41701741f19a9AA508F44bfd", + "commbankDotEth#CommBankDotEth": "0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA" } diff --git a/contracts/ignition/deployments/chain-11155111/journal.jsonl b/contracts/ignition/deployments/chain-11155111/journal.jsonl index e8e17f4..0fe804b 100644 --- a/contracts/ignition/deployments/chain-11155111/journal.jsonl +++ b/contracts/ignition/deployments/chain-11155111/journal.jsonl @@ -2,43 +2,55 @@ {"chainId":11155111,"type":"DEPLOYMENT_INITIALIZE"} {"artifactId":"depositVerifier#DepositVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/DepositVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} {"futureId":"depositVerifier#DepositVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":77,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":77,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000062"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0xfb8e14c084e2b2507217aa540abb8f3723f5618570ca1edc84aa7baa898ca8ca"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":98,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":98,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2177081414"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x20dabc7a5512baea74d7dc3fc477c6d5eef2a397b5c15e958ab940c5a240f65b"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferExternalVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":99,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":99,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2177081414"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0xa86c7785531ec2237cfbad1ac4f8de2c79fe9f05535fdd4afd406be53ecc7418"},"type":"TRANSACTION_SEND"} {"artifactId":"transferVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} {"futureId":"transferVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":78,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":78,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000068"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0x9cd477534dd47907ef5c1f6a30a9e88ced67b7519f3c6768a556f4ade832c786"},"type":"TRANSACTION_SEND"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":100,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":100,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2177081414"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x4ce7f67a9eec5eb8605948ca4e2a5ebe67179d9603905a0ae3f288a782ac4705"},"type":"TRANSACTION_SEND"} {"artifactId":"withdrawVerifier#WithdrawVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/WithdrawVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} {"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":79,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":79,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000068"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0xbf14bc98493ebd5b5fc6de1ebd8ac7927885fc6587c39b6043bcf9a5f45d6b40"},"type":"TRANSACTION_SEND"} -{"futureId":"depositVerifier#DepositVerifierLib","hash":"0xfb8e14c084e2b2507217aa540abb8f3723f5618570ca1edc84aa7baa898ca8ca","networkInteractionId":1,"receipt":{"blockHash":"0x556c430cd0d5470ed69cd5ea56eb57901e84b373ad9483b61c01e12518b390a3","blockNumber":9815667,"contractAddress":"0x4AD5C3d68C5038AfE010EcF9d3041Aa068Da6D11","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"depositVerifier#DepositVerifierLib","result":{"address":"0x4AD5C3d68C5038AfE010EcF9d3041Aa068Da6D11","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"futureId":"transferVerifier#TransferVerifierLib","hash":"0x9cd477534dd47907ef5c1f6a30a9e88ced67b7519f3c6768a556f4ade832c786","networkInteractionId":1,"receipt":{"blockHash":"0x556c430cd0d5470ed69cd5ea56eb57901e84b373ad9483b61c01e12518b390a3","blockNumber":9815667,"contractAddress":"0xA7edA38ae0Ebb9150172A72Aed3c94e1b7b75369","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"transferVerifier#TransferVerifierLib","result":{"address":"0xA7edA38ae0Ebb9150172A72Aed3c94e1b7b75369","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"futureId":"withdrawVerifier#WithdrawVerifierLib","hash":"0xbf14bc98493ebd5b5fc6de1ebd8ac7927885fc6587c39b6043bcf9a5f45d6b40","networkInteractionId":1,"receipt":{"blockHash":"0x556c430cd0d5470ed69cd5ea56eb57901e84b373ad9483b61c01e12518b390a3","blockNumber":9815667,"contractAddress":"0xeBfD88f112cC69c3cd02C846f4eAD8759B4aE7F3","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"withdrawVerifier#WithdrawVerifierLib","result":{"address":"0xeBfD88f112cC69c3cd02C846f4eAD8759B4aE7F3","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"artifactId":"depositVerifier#DepositVerifier","constructorArgs":[],"contractName":"DepositVerifier","dependencies":["depositVerifier#DepositVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x4AD5C3d68C5038AfE010EcF9d3041Aa068Da6D11"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"depositVerifier#DepositVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f90734AD5C3d68C5038AfE010EcF9d3041Aa068Da6D119063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":80,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":80,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000066"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0x77b951213bb767c5561be822d9a59bce5478abd1347215d839c664f193c48fc5"},"type":"TRANSACTION_SEND"} -{"artifactId":"transferVerifier#TransferVerifier","constructorArgs":[],"contractName":"TransferVerifier","dependencies":["transferVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xA7edA38ae0Ebb9150172A72Aed3c94e1b7b75369"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"transferVerifier#TransferVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073A7edA38ae0Ebb9150172A72Aed3c94e1b7b753699063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":81,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":81,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000066"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0x18aecc376e240181f76931306c31397483f3759b059afb19d8ac0325f1d329d9"},"type":"TRANSACTION_SEND"} -{"artifactId":"withdrawVerifier#WithdrawVerifier","constructorArgs":[],"contractName":"WithdrawVerifier","dependencies":["withdrawVerifier#WithdrawVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xeBfD88f112cC69c3cd02C846f4eAD8759B4aE7F3"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073eBfD88f112cC69c3cd02C846f4eAD8759B4aE7F39063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":82,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":82,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000066"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0x3194d195a380c3e1a092674486e0bdfbfae8db57b15ccc909f750fb936c35d71"},"type":"TRANSACTION_SEND"} -{"futureId":"depositVerifier#DepositVerifier","hash":"0x77b951213bb767c5561be822d9a59bce5478abd1347215d839c664f193c48fc5","networkInteractionId":1,"receipt":{"blockHash":"0x57043b59fb594341a58f5d124d7530a7a4630caa750d400e37f622b683ac75d3","blockNumber":9815672,"contractAddress":"0x44C4589Ceb6C358044014CC4120D02495b68C2F7","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"depositVerifier#DepositVerifier","result":{"address":"0x44C4589Ceb6C358044014CC4120D02495b68C2F7","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"futureId":"transferVerifier#TransferVerifier","hash":"0x18aecc376e240181f76931306c31397483f3759b059afb19d8ac0325f1d329d9","networkInteractionId":1,"receipt":{"blockHash":"0x57043b59fb594341a58f5d124d7530a7a4630caa750d400e37f622b683ac75d3","blockNumber":9815672,"contractAddress":"0x4875435f82a0B2abda43BF6E5fA2A66FEc25746B","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"transferVerifier#TransferVerifier","result":{"address":"0x4875435f82a0B2abda43BF6E5fA2A66FEc25746B","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"futureId":"withdrawVerifier#WithdrawVerifier","hash":"0x3194d195a380c3e1a092674486e0bdfbfae8db57b15ccc909f750fb936c35d71","networkInteractionId":1,"receipt":{"blockHash":"0x57043b59fb594341a58f5d124d7530a7a4630caa750d400e37f622b683ac75d3","blockNumber":9815672,"contractAddress":"0x05796fA1Df106917cbC82DDB3B3449CEDed43734","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"withdrawVerifier#WithdrawVerifier","result":{"address":"0x05796fA1Df106917cbC82DDB3B3449CEDed43734","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"artifactId":"commbankDotEth#CommBankDotEth","constructorArgs":["0x44C4589Ceb6C358044014CC4120D02495b68C2F7","0x4875435f82a0B2abda43BF6E5fA2A66FEc25746B","0x05796fA1Df106917cbC82DDB3B3449CEDed43734"],"contractName":"CommBankDotEth","dependencies":["depositVerifier#DepositVerifier","transferVerifier#TransferVerifier","withdrawVerifier#WithdrawVerifier"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"commbankDotEth#CommBankDotEth","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"commbankDotEth#CommBankDotEth","networkInteraction":{"data":"0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600c5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b5060405161256538038061256583398101604081905261007b91610218565b600c608081905261008d60018261026c565b610098906002610362565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0388811691909117909155600980548316878316179055600a80549092169085161790556101399190610150565b50600c546101479033610150565b50505050610374565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff166101f4575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101ac3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016101f7565b505f5b92915050565b80516001600160a01b0381168114610213575f5ffd5b919050565b5f5f5f6060848603121561022a575f5ffd5b610233846101fd565b9250610241602085016101fd565b915061024f604085016101fd565b90509250925092565b634e487b7160e01b5f52601160045260245ffd5b818103818111156101f7576101f7610258565b6001815b60018411156102ba5780850481111561029e5761029e610258565b60018416156102ac57908102905b60019390931c928002610283565b935093915050565b5f826102d0575060016101f7565b816102dc57505f6101f7565b81600181146102f257600281146102fc57610318565b60019150506101f7565b60ff84111561030d5761030d610258565b50506001821b6101f7565b5060208310610133831016604e8410600b841016171561033b575081810a6101f7565b6103475f19848461027f565b805f190482111561035a5761035a610258565b029392505050565b5f61036d83836102c2565b9392505050565b60805160a0516121bb6103aa5f395f81816104b301528181610b1701526114a101525f81816102280152611a0001526121bb5ff3fe60806040526004361061019e575f3560e01c80638daed528116100df578063c2b40ae411610083578063c2b40ae414610527578063c46165b514610552578063cd87a3b414610565578063d547741f14610579578063d5f3948814610598578063e8295588146105b7578063f178e47c146105d6578063fc7e9c6f14610601575f5ffd5b80638daed5281461040157806390eeb02b1461042057806391d1485414610451578063a217fddf14610470578063a6232a9314610483578063a734f06e146104a2578063aa77c44a146104d5578063b42147cd146104f4575f5ffd5b806336568abe1161014657806336568abe146103045780635bb93995146103235780635e125d0d1461034257806367843a5b146103615780637ecf686d1461038057806380fc7498146103ae57806384746900146103c3578063864eb164146103e2575f5ffd5b806217cd8b146101a257806301ffc9a7146101e85780630ef26743146102175780631a702a241461024a578063248a9ca31461028157806326120c88146102af5780632f2ff15d146102ce578063353efdcf146102ef575b5f5ffd5b3480156101ad575f5ffd5b506101d57f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b3480156101f3575f5ffd5b50610207610202366004611bc4565b610616565b60405190151581526020016101df565b348015610222575f5ffd5b506101d57f000000000000000000000000000000000000000000000000000000000000000081565b348015610255575f5ffd5b50600554610269906001600160a01b031681565b6040516001600160a01b0390911681526020016101df565b34801561028c575f5ffd5b506101d561029b366004611bf2565b5f9081526007602052604090206001015490565b3480156102ba575f5ffd5b50600854610269906001600160a01b031681565b3480156102d9575f5ffd5b506102ed6102e8366004611c1f565b61064c565b005b3480156102fa575f5ffd5b506101d5600c5481565b34801561030f575f5ffd5b506102ed61031e366004611c1f565b610676565b34801561032e575f5ffd5b506101d561033d366004611c49565b6106ae565b34801561034d575f5ffd5b506102ed61035c366004611c69565b6107a6565b34801561036c575f5ffd5b506102ed61037b366004611d06565b610871565b34801561038b575f5ffd5b5061020761039a366004611bf2565b600b6020525f908152604090205460ff1681565b3480156103b9575f5ffd5b506101d560045481565b3480156103ce575f5ffd5b506102ed6103dd366004611d70565b610d0a565b3480156103ed575f5ffd5b50600a54610269906001600160a01b031681565b34801561040c575f5ffd5b50600954610269906001600160a01b031681565b34801561042b575f5ffd5b5060025461043c9063ffffffff1681565b60405163ffffffff90911681526020016101df565b34801561045c575f5ffd5b5061020761046b366004611c1f565b61102d565b34801561047b575f5ffd5b506101d55f81565b34801561048e575f5ffd5b5061020761049d366004611bf2565b611057565b3480156104ad575f5ffd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e0575f5ffd5b506102ed6104ef366004611e0c565b6110d0565b3480156104ff575f5ffd5b506101d57f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610532575f5ffd5b506101d5610541366004611bf2565b60016020525f908152604090205481565b6102ed610560366004611d70565b6113d9565b348015610570575f5ffd5b5061043c606481565b348015610584575f5ffd5b506102ed610593366004611c1f565b61162c565b3480156105a3575f5ffd5b50600654610269906001600160a01b031681565b3480156105c2575f5ffd5b506101d56105d1366004611bf2565b611650565b3480156105e1575f5ffd5b506101d56105f0366004611bf2565b5f6020819052908152604090205481565b34801561060c575f5ffd5b506101d560035481565b5f6001600160e01b03198216637965db0b60e01b148061064657506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f8281526007602052604090206001015461066681611898565b61067083836118a5565b50505050565b6001600160a01b038116331461069f5760405163334bd91960e11b815260040160405180910390fd5b6106a98282611936565b505050565b5f5f83836040516020016106cc929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906106fc908590611ec1565b5f60405180830381855afa9150503d805f8114610734576040519150601f19603f3d011682016040523d82523d5f602084013e610739565b606091505b5091509150816107885760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b8080602001905181019061079c9190611ed7565b9695505050505050565b6005546001600160a01b0316156107f55760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b604482015260640161077f565b6006546001600160a01b0316331461084f5760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e0000604482015260640161077f565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b61089482825f81811061088657610886611eee565b905060200201355f1c611057565b6108b05760405162461bcd60e51b815260040161077f90611f02565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906108e6908890889088908890600401611f51565b6020604051808303815f875af1158015610902573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109269190611f9b565b90508061096e5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604482015260640161077f565b60015b60038111610a7f575f84848381811061098c5761098c611eee565b9050602002013514610a6d57600b5f8585848181106109ad576109ad611eee565b602090810292909201358352508101919091526040015f205460ff16156109e65760405162461bcd60e51b815260040161077f90611fba565b6001600b5f8686858181106109fd576109fd611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a3957610a39611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b80610a7781611fff565b915050610971565b505f5b6003811015610d02575f610a97826004612017565b90505f610aa5836007612017565b90505f610ab384600a612017565b90505f878785818110610ac857610ac8611eee565b905060200201355f1c90505f888885818110610ae657610ae6611eee565b905060200201355f1c90505f898985818110610b0457610b04611eee565b60200291909101359150508115610cf0577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c345781471015610b995760405162461bcd60e51b8152602060048201526018602482015277496e73756666696369656e74204554482062616c616e636560401b604482015260640161077f565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610be2576040519150601f19603f3d011682016040523d82523d5f602084013e610be7565b606091505b5050905080610c2e5760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161077f565b50610cf0565b60405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490525f919085169063a9059cbb906044016020604051808303815f875af1158015610c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca79190611f9b565b905080610cee5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604482015260640161077f565b505b505060019094019350610a8292505050565b505050505050565b610d1f84845f81811061088657610886611eee565b610d3b5760405162461bcd60e51b815260040161077f90611f02565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d71908a908a908a908a90600401611f51565b6020604051808303815f875af1158015610d8d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db19190611f9b565b905080610df95760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b604482015260640161077f565b60015b610e0860036001612017565b811015610f0b575f868683818110610e2257610e22611eee565b9050602002013514610f0357600b5f878784818110610e4357610e43611eee565b602090810292909201358352508101919091526040015f205460ff1615610e7c5760405162461bcd60e51b815260040161077f90611fba565b6001600b5f888885818110610e9357610e93611eee565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610ecf57610ecf611eee565b905060200201357f4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c60405160405180910390a25b600101610dfc565b505f610f1960036001612017565b90505b6003610f29816001612017565b610f339190612017565b811015610f86575f868683818110610f4d57610f4d611eee565b9050602002013514610f7e57610f7c868683818110610f6e57610f6e611eee565b905060200201355f1c6119a1565b505b600101610f1c565b505f5b600381108015610f9857508281105b1561102357838382818110610faf57610faf611eee565b9050602002810190610fc1919061202a565b159050611011575f5160206121665f395f51905f52848483818110610fe857610fe8611eee565b9050602002810190610ffa919061202a565b60405161100892919061206c565b60405180910390a15b8061101b81611fff565b915050610f89565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361106657505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611096575060019392505050565b8063ffffffff165f036110a7575060645b806110b181612087565b9150508163ffffffff168163ffffffff160361107157505f9392505050565b600c546110dc81611898565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af115801561112e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111529190611f9b565b9050806111a15760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f736974000000000000604482015260640161077f565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906111d7908c908c908c908c90600401611f51565b6020604051808303815f875af11580156111f3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112179190611f9b565b9050806112365760405162461bcd60e51b815260040161077f906120a5565b8686600181811061124957611249611eee565b905060200201355f1c6001600160a01b03168b6001600160a01b0316146112ab5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b604482015260640161077f565b868660028181106112be576112be611eee565b905060200201355f1c6001600160401b03168a146113195760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b604482015260640161077f565b61132e87875f818110610f6e57610f6e611eee565b505f5b60038110801561134057508481105b156113cb5785858281811061135757611357611eee565b9050602002810190611369919061202a565b1590506113b9575f5160206121665f395f51905f5286868381811061139057611390611eee565b90506020028101906113a2919061202a565b6040516113b092919061206c565b60405180910390a15b806113c381611fff565b915050611331565b505050505050505050505050565b600c546113e581611898565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061141b908b908b908b908b90600401611f51565b6020604051808303815f875af1158015611437573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145b9190611f9b565b90508061147a5760405162461bcd60e51b815260040161077f906120a5565b8585600181811061148d5761148d611eee565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146115095760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b604482015260640161077f565b8585600281811061151c5761151c611eee565b905060200201355f1c6001600160401b0316341461156f5760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b604482015260640161077f565b61158486865f818110610f6e57610f6e611eee565b505f5b60038110801561159657508381105b15611621578484828181106115ad576115ad611eee565b90506020028101906115bf919061202a565b15905061160f575f5160206121665f395f51905f528585838181106115e6576115e6611eee565b90506020028101906115f8919061202a565b60405161160692919061206c565b60405180910390a15b8061161981611fff565b915050611587565b505050505050505050565b5f8281526007602052604090206001015461164681611898565b6106708383611936565b5f815f0361167f57507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b816001036116ae57507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b816002036116dd57507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b8160030361170c57507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b8160040361173b57507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b8160050361176a57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b8160060361179957507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b816007036117c857507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b816008036117f757507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b8160090361182657507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a0361185557507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b604482015260640161077f565b919050565b6118a28133611b87565b50565b5f6118b0838361102d565b61192f575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556118e73390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610646565b505f610646565b5f611941838361102d565b1561192f575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610646565b6003546004545f919081036119e45760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b604482015260640161077f565b5f818152602081905260408120849055819084905b611a2460017f00000000000000000000000000000000000000000000000000000000000000006120d5565b811015611af1575f611a376002856120fc565b1590505f81611a5057611a4b6001866120d5565b611a5b565b611a5b856001612017565b602084811b82175f8181529182905260408220549293509190819003611a8757611a8485611650565b90505b8315611a9e57611a9786826106ae565b9550611aab565b611aa881876106ae565b95505b611ab660028861210f565b9650855f80611ad1611ac9896001612017565b60201b8b1790565b815260208101919091526040015f20555050600190920191506119f99050565b506002545f90606490611b0b9063ffffffff166001612122565b611b15919061213e565b6002805463ffffffff191663ffffffff83169081179091555f908152600160208190526040909120849055909150611b4e908590612017565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b611b91828261102d565b611bc05760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161077f565b5050565b5f60208284031215611bd4575f5ffd5b81356001600160e01b031981168114611beb575f5ffd5b9392505050565b5f60208284031215611c02575f5ffd5b5035919050565b80356001600160a01b0381168114611893575f5ffd5b5f5f60408385031215611c30575f5ffd5b82359150611c4060208401611c09565b90509250929050565b5f5f60408385031215611c5a575f5ffd5b50508035926020909101359150565b5f60208284031215611c79575f5ffd5b611beb82611c09565b5f5f83601f840112611c92575f5ffd5b5081356001600160401b03811115611ca8575f5ffd5b602083019150836020828501011115611cbf575f5ffd5b9250929050565b5f5f83601f840112611cd6575f5ffd5b5081356001600160401b03811115611cec575f5ffd5b6020830191508360208260051b8501011115611cbf575f5ffd5b5f5f5f5f60408587031215611d19575f5ffd5b84356001600160401b03811115611d2e575f5ffd5b611d3a87828801611c82565b90955093505060208501356001600160401b03811115611d58575f5ffd5b611d6487828801611cc6565b95989497509550505050565b5f5f5f5f5f5f60608789031215611d85575f5ffd5b86356001600160401b03811115611d9a575f5ffd5b611da689828a01611c82565b90975095505060208701356001600160401b03811115611dc4575f5ffd5b611dd089828a01611cc6565b90955093505060408701356001600160401b03811115611dee575f5ffd5b611dfa89828a01611cc6565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b031215611e23575f5ffd5b611e2c89611c09565b97506020890135965060408901356001600160401b03811115611e4d575f5ffd5b611e598b828c01611c82565b90975095505060608901356001600160401b03811115611e77575f5ffd5b611e838b828c01611cc6565b90955093505060808901356001600160401b03811115611ea1575f5ffd5b611ead8b828c01611cc6565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611ee7575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f611f64604083018688611f29565b82810360208401528381526001600160fb1b03841115611f82575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215611fab575f5ffd5b81518015158114611beb575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161201057612010611feb565b5060010190565b8082018082111561064657610646611feb565b5f5f8335601e1984360301811261203f575f5ffd5b8301803591506001600160401b03821115612058575f5ffd5b602001915036819003821315611cbf575f5ffd5b602081525f61207f602083018486611f29565b949350505050565b5f63ffffffff82168061209c5761209c611feb565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561064657610646611feb565b634e487b7160e01b5f52601260045260245ffd5b5f8261210a5761210a6120e8565b500690565b5f8261211d5761211d6120e8565b500490565b63ffffffff818116838216019081111561064657610646611feb565b5f63ffffffff831680612153576121536120e8565b8063ffffffff8416069150509291505056fe1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a2646970667358221220e72906da9e01e129b73110391184b6af4deda5d0bbed1a05cbfb6d409dffbda164736f6c634300081c003300000000000000000000000044c4589ceb6c358044014cc4120d02495b68c2f70000000000000000000000004875435f82a0b2abda43bf6e5fa2a66fec25746b00000000000000000000000005796fa1df106917cbc82ddb3b3449ceded43734","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":83,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":83,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1000064"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000"}},"hash":"0x3d0482887bdbd7e8c712cedc49dd8a2841ec39e2490bafe92b405b3b8e8f446c"},"type":"TRANSACTION_SEND"} -{"futureId":"commbankDotEth#CommBankDotEth","hash":"0x3d0482887bdbd7e8c712cedc49dd8a2841ec39e2490bafe92b405b3b8e8f446c","networkInteractionId":1,"receipt":{"blockHash":"0x9471749dd91892f63c416d0d5ad654e96553145a232a4fc52acac452be07fa2c","blockNumber":9815677,"contractAddress":"0x582E8C09955727112014B50A4eB3978697CDCB77","logs":[{"address":"0x582E8C09955727112014B50A4eB3978697CDCB77","data":"0x","logIndex":129,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]},{"address":"0x582E8C09955727112014B50A4eB3978697CDCB77","data":"0x","logIndex":130,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"commbankDotEth#CommBankDotEth","result":{"address":"0x582E8C09955727112014B50A4eB3978697CDCB77","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":101,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":101,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2177081414"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x8a9c3542a577d52ff19b485efcf1286e1a664029fcfe1e3431aeb0ac025af389"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","hash":"0x20dabc7a5512baea74d7dc3fc477c6d5eef2a397b5c15e958ab940c5a240f65b","networkInteractionId":1,"receipt":{"blockHash":"0x41979c83eb7a41a814c75d6f2fc5f4513312de3c1da8493af3be9e73f0b3542b","blockNumber":10047014,"contractAddress":"0xEf3cB11Af34F9163ADb870074252dD49a484d664","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifierLib","result":{"address":"0xEf3cB11Af34F9163ADb870074252dD49a484d664","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","hash":"0xa86c7785531ec2237cfbad1ac4f8de2c79fe9f05535fdd4afd406be53ecc7418","networkInteractionId":1,"receipt":{"blockHash":"0x41979c83eb7a41a814c75d6f2fc5f4513312de3c1da8493af3be9e73f0b3542b","blockNumber":10047014,"contractAddress":"0x9070f3c785C901d4d825D5d28d1aeD4Ae4e49d3b","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","result":{"address":"0x9070f3c785C901d4d825D5d28d1aeD4Ae4e49d3b","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifierLib","hash":"0x4ce7f67a9eec5eb8605948ca4e2a5ebe67179d9603905a0ae3f288a782ac4705","networkInteractionId":1,"receipt":{"blockHash":"0x41979c83eb7a41a814c75d6f2fc5f4513312de3c1da8493af3be9e73f0b3542b","blockNumber":10047014,"contractAddress":"0x33528772d99Bf7afF96Db20321638664019CC40C","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifierLib","result":{"address":"0x33528772d99Bf7afF96Db20321638664019CC40C","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","hash":"0x8a9c3542a577d52ff19b485efcf1286e1a664029fcfe1e3431aeb0ac025af389","networkInteractionId":1,"receipt":{"blockHash":"0x1c120fd6247ba8b9f18d6c35f95edd89cffdadf169645cffe684cfc5aa96c5ac","blockNumber":10047016,"contractAddress":"0x60b721B9b7c103cB010CfC1844ddD3c6eA5D4E47","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","result":{"address":"0x60b721B9b7c103cB010CfC1844ddD3c6eA5D4E47","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"depositVerifier#DepositVerifier","constructorArgs":[],"contractName":"DepositVerifier","dependencies":["depositVerifier#DepositVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xEf3cB11Af34F9163ADb870074252dD49a484d664"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"depositVerifier#DepositVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073Ef3cB11Af34F9163ADb870074252dD49a484d6649063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":102,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":102,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2238641246"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0xa93d7ac74510ef7c69f26c61e3dd500dd48ab4dd5c359cf124b5f86a20a2d9e0"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferExternalVerifier","constructorArgs":[],"contractName":"TransferExternalVerifier","dependencies":["transferExternalVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferExternalVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x9070f3c785C901d4d825D5d28d1aeD4Ae4e49d3b"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f90739070f3c785C901d4d825D5d28d1aeD4Ae4e49d3b9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":103,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":103,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2238641246"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x016efb78a1479f3381b0718acd63ab693716f40ba6a6d308db9d4a54bf0585fc"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferVerifier#TransferVerifier","constructorArgs":[],"contractName":"TransferVerifier","dependencies":["transferVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x33528772d99Bf7afF96Db20321638664019CC40C"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferVerifier#TransferVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f907333528772d99Bf7afF96Db20321638664019CC40C9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":104,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":104,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2238641246"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x48a5bbfbb9335cb06eeefc52845ec393215fc4592b62a01c9aa86ed4feccb5be"},"type":"TRANSACTION_SEND"} +{"artifactId":"withdrawVerifier#WithdrawVerifier","constructorArgs":[],"contractName":"WithdrawVerifier","dependencies":["withdrawVerifier#WithdrawVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x60b721B9b7c103cB010CfC1844ddD3c6eA5D4E47"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f907360b721B9b7c103cB010CfC1844ddD3c6eA5D4E479063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":105,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":105,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2238641246"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x8d735bb9704afc8d0cbad1f8e2a699828f311fc447729d611a15ae292b0045c3"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifier","hash":"0xa93d7ac74510ef7c69f26c61e3dd500dd48ab4dd5c359cf124b5f86a20a2d9e0","networkInteractionId":1,"receipt":{"blockHash":"0x9c3db5476639e36e1ce7b052b3834f8916c9fc00422343a8429504d8f3c79093","blockNumber":10047021,"contractAddress":"0x9d29CfBF46c8779FB699fd4725651eA26dfb5678","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifier","result":{"address":"0x9d29CfBF46c8779FB699fd4725651eA26dfb5678","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","hash":"0x016efb78a1479f3381b0718acd63ab693716f40ba6a6d308db9d4a54bf0585fc","networkInteractionId":1,"receipt":{"blockHash":"0x9c3db5476639e36e1ce7b052b3834f8916c9fc00422343a8429504d8f3c79093","blockNumber":10047021,"contractAddress":"0x77c4665654Af3822A35EB51cF1a42494C7a5047F","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","result":{"address":"0x77c4665654Af3822A35EB51cF1a42494C7a5047F","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifier","hash":"0x48a5bbfbb9335cb06eeefc52845ec393215fc4592b62a01c9aa86ed4feccb5be","networkInteractionId":1,"receipt":{"blockHash":"0x9c3db5476639e36e1ce7b052b3834f8916c9fc00422343a8429504d8f3c79093","blockNumber":10047021,"contractAddress":"0xC4Bdd4CF56a974D8021e5c7Ad837Afa18ACbFf46","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifier","result":{"address":"0xC4Bdd4CF56a974D8021e5c7Ad837Afa18ACbFf46","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifier","hash":"0x8d735bb9704afc8d0cbad1f8e2a699828f311fc447729d611a15ae292b0045c3","networkInteractionId":1,"receipt":{"blockHash":"0x9c3db5476639e36e1ce7b052b3834f8916c9fc00422343a8429504d8f3c79093","blockNumber":10047021,"contractAddress":"0xae59070836A08C4F41701741f19a9AA508F44bfd","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifier","result":{"address":"0xae59070836A08C4F41701741f19a9AA508F44bfd","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"commbankDotEth#CommBankDotEth","constructorArgs":["0x9d29CfBF46c8779FB699fd4725651eA26dfb5678","0xC4Bdd4CF56a974D8021e5c7Ad837Afa18ACbFf46","0xae59070836A08C4F41701741f19a9AA508F44bfd","0x77c4665654Af3822A35EB51cF1a42494C7a5047F"],"contractName":"CommBankDotEth","dependencies":["depositVerifier#DepositVerifier","transferVerifier#TransferVerifier","withdrawVerifier#WithdrawVerifier","transferExternalVerifier#TransferExternalVerifier"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"commbankDotEth#CommBankDotEth","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteraction":{"data":"0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c00330000000000000000000000009d29cfbf46c8779fb699fd4725651ea26dfb5678000000000000000000000000c4bdd4cf56a974d8021e5c7ad837afa18acbff46000000000000000000000000ae59070836a08c4f41701741f19a9aa508f44bfd00000000000000000000000077c4665654af3822a35eb51cf1a42494c7a5047f","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":106,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":106,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"1944289674"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"5000000"}},"hash":"0x388850531170ef36ee83e36cf15329c050919f94e12e8ac9e486cbd67e45b1a5"},"type":"TRANSACTION_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","hash":"0x388850531170ef36ee83e36cf15329c050919f94e12e8ac9e486cbd67e45b1a5","networkInteractionId":1,"receipt":{"blockHash":"0x4a598f6f16ef4c4da29e8e78594971bd1b608cc28a41db0a6fa81c586678f281","blockNumber":10047026,"contractAddress":"0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA","logs":[{"address":"0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA","data":"0x","logIndex":129,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]},{"address":"0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA","data":"0x","logIndex":130,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"commbankDotEth#CommBankDotEth","result":{"address":"0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/commbankDotEth#CommBankDotEth.json b/contracts/ignition/deployments/chain-421614/artifacts/commbankDotEth#CommBankDotEth.json new file mode 100644 index 0000000..d2ad067 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/commbankDotEth#CommBankDotEth.json @@ -0,0 +1,786 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "CommBankDotEth", + "sourceName": "contracts/CommBankDotEth.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_noteVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_transactVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawalVerifier", + "type": "address" + }, + { + "internalType": "address", + "name": "_transferExternalVerifier", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "leafIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "leafValue", + "type": "bytes32" + } + ], + "name": "LeafInserted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "encryptedNote", + "type": "bytes" + } + ], + "name": "NotePayload", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "nullifier", + "type": "bytes32" + } + ], + "name": "NullifierUsed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEPOSIT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_ROOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LEAF_INDEX", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ROOT_HISTORY_SIZE", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentRootIndex", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deployer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_erc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "depositNative", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "filledSubtrees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_left", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_right", + "type": "uint256" + } + ], + "name": "hashLeftRight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "height", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_root", + "type": "uint256" + } + ], + "name": "isKnownRoot", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "nullifierUsed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poseidon2Hasher", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "roots", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_hasher", + "type": "address" + } + ], + "name": "setPoseidon", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes[]", + "name": "_payload", + "type": "bytes[]" + } + ], + "name": "transferExternal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferExternalVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "i", + "type": "uint256" + } + ], + "name": "zeros", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", + "deployedBytecode": "0x6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": { + "576": [ + { + "length": 32, + "start": 1225 + }, + { + "length": 32, + "start": 2904 + }, + { + "length": 32, + "start": 5813 + }, + { + "length": 32, + "start": 6550 + } + ], + "1525": [ + { + "length": 32, + "start": 574 + }, + { + "length": 32, + "start": 7925 + } + ] + }, + "inputSourceName": "project/contracts/CommBankDotEth.sol", + "buildInfoId": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifier.json b/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifier.json new file mode 100644 index 0000000..b6ce8d1 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "DepositVerifier", + "sourceName": "contracts/verifiers/DepositVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$848e18252827b7ad91b03e1d1be9251966$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$848e18252827b7ad91b03e1d1be9251966$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/DepositVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/DepositVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11157 + }, + { + "length": 32, + "start": 11966 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/DepositVerifier.sol", + "buildInfoId": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifierLib.json b/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifierLib.json new file mode 100644 index 0000000..a881b33 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/depositVerifier#DepositVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/DepositVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/DepositVerifier.sol", + "buildInfoId": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/tokens#AUDD.json b/contracts/ignition/deployments/chain-421614/artifacts/tokens#AUDD.json new file mode 100644 index 0000000..89b0163 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/tokens#AUDD.json @@ -0,0 +1,345 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "AUDD", + "sourceName": "contracts/mocks/AUDD.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "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": "value", + "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": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561000f575f5ffd5b506040805180820182526004808252631055511160e21b602080840182905284518086019095529184529083015290600361004a838261026e565b506004610057828261026e565b50505061006e33633b9aca0061007360201b60201c565b61034d565b6001600160a01b0382166100a15760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ac5f83836100b0565b5050565b6001600160a01b0383166100da578060025f8282546100cf9190610328565b9091555061014a9050565b6001600160a01b0383165f908152602081905260409020548181101561012c5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610098565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016657600280548290039055610184565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101c991815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806101fe57607f821691505b60208210810361021c57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026957805f5260205f20601f840160051c810160208510156102475750805b601f840160051c820191505b81811015610266575f8155600101610253565b50505b505050565b81516001600160401b03811115610287576102876101d6565b61029b8161029584546101ea565b84610222565b6020601f8211600181146102cd575f83156102b65750848201515b5f19600385901b1c1916600184901b178455610266565b5f84815260208120601f198516915b828110156102fc57878501518255602094850194600190920191016102dc565b508482101561031957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034757634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035a5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220ec03718ff94b552bfffd8fec13417b7e7ca5c7ae77ec71d1e8c9060cda1cd96e64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220ec03718ff94b552bfffd8fec13417b7e7ca5c7ae77ec71d1e8c9060cda1cd96e64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/mocks/AUDD.sol", + "buildInfoId": "solc-0_8_28-ad0cc7caf95bc67952c9cdec84ad3dce5a76ea7e" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/tokens#FourDEC.json b/contracts/ignition/deployments/chain-421614/artifacts/tokens#FourDEC.json new file mode 100644 index 0000000..7683576 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/tokens#FourDEC.json @@ -0,0 +1,345 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "FourDEC", + "sourceName": "contracts/mocks/FourDEC.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "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": "value", + "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": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561000f575f5ffd5b50604080518082018252600780825266466f757244454360c81b602080840182905284518086019095529184529083015290600361004d8382610270565b50600461005a8282610270565b505050610070336298968061007560201b60201c565b61034f565b6001600160a01b0382166100a35760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ae5f83836100b2565b5050565b6001600160a01b0383166100dc578060025f8282546100d1919061032a565b9091555061014c9050565b6001600160a01b0383165f908152602081905260409020548181101561012e5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161009a565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016857600280548290039055610186565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101cb91815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061020057607f821691505b60208210810361021e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026b57805f5260205f20601f840160051c810160208510156102495750805b601f840160051c820191505b81811015610268575f8155600101610255565b50505b505050565b81516001600160401b03811115610289576102896101d8565b61029d8161029784546101ec565b84610224565b6020601f8211600181146102cf575f83156102b85750848201515b5f19600385901b1c1916600184901b178455610268565b5f84815260208120601f198516915b828110156102fe57878501518255602094850194600190920191016102de565b508482101561031b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034957634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035c5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600481526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220de39d23dc8cf5d145e964ff008ad8dc2391d50090a52cd0410790e031fc99c2e64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600481526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220de39d23dc8cf5d145e964ff008ad8dc2391d50090a52cd0410790e031fc99c2e64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/mocks/FourDEC.sol", + "buildInfoId": "solc-0_8_28-cd3964288f6c44135c197c8203659aefd819d931" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/tokens#USDC.json b/contracts/ignition/deployments/chain-421614/artifacts/tokens#USDC.json new file mode 100644 index 0000000..cf893a5 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/tokens#USDC.json @@ -0,0 +1,345 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "USDC", + "sourceName": "contracts/mocks/USDC.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "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": "value", + "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": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561000f575f5ffd5b506040805180820182526004808252635553444360e01b602080840182905284518086019095529184529083015290600361004a838261026e565b506004610057828261026e565b50505061006e33633b9aca0061007360201b60201c565b61034d565b6001600160a01b0382166100a15760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ac5f83836100b0565b5050565b6001600160a01b0383166100da578060025f8282546100cf9190610328565b9091555061014a9050565b6001600160a01b0383165f908152602081905260409020548181101561012c5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610098565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016657600280548290039055610184565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101c991815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806101fe57607f821691505b60208210810361021c57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026957805f5260205f20601f840160051c810160208510156102475750805b601f840160051c820191505b81811015610266575f8155600101610253565b50505b505050565b81516001600160401b03811115610287576102876101d6565b61029b8161029584546101ea565b84610222565b6020601f8211600181146102cd575f83156102b65750848201515b5f19600385901b1c1916600184901b178455610266565b5f84815260208120601f198516915b828110156102fc57878501518255602094850194600190920191016102dc565b508482101561031957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034757634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035a5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea26469706673582212201cfb0beb6ebddb40b7047788b0cede7eb1b4e67bb1b9174e2f81a21ba6a89c6364736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea26469706673582212201cfb0beb6ebddb40b7047788b0cede7eb1b4e67bb1b9174e2f81a21ba6a89c6364736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/mocks/USDC.sol", + "buildInfoId": "solc-0_8_28-c8eaf1e731d163f064d4197bfb5b0c7e14f49296" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferExternalVerifier.json b/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferExternalVerifier.json new file mode 100644 index 0000000..f76e480 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferExternalVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "TransferExternalVerifier", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$45dbc918ddfbc8c6bbc5e9f572af59f43e$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11156 + }, + { + "length": 32, + "start": 11965 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferVerifierLib.json b/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferVerifierLib.json new file mode 100644 index 0000000..b1151dc --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/transferExternalVerifier#TransferVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/TransferExternalVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/TransferExternalVerifier.sol", + "buildInfoId": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifier.json b/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifier.json new file mode 100644 index 0000000..bc84c2e --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "TransferVerifier", + "sourceName": "contracts/verifiers/TransferVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$8ca614531f81a5db991ca8a5216cacce22$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$8ca614531f81a5db991ca8a5216cacce22$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/TransferVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/TransferVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11154 + }, + { + "length": 32, + "start": 11963 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/TransferVerifier.sol", + "buildInfoId": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifierLib.json b/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifierLib.json new file mode 100644 index 0000000..1e0d5dd --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/transferVerifier#TransferVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/TransferVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/TransferVerifier.sol", + "buildInfoId": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifier.json b/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifier.json new file mode 100644 index 0000000..c3e97cf --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifier.json @@ -0,0 +1,186 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "WithdrawVerifier", + "sourceName": "contracts/verifiers/WithdrawVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ConsistencyCheckFailed", + "type": "error" + }, + { + "inputs": [], + "name": "GeminiChallengeInSubgroup", + "type": "error" + }, + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + } + ], + "name": "ProofLengthWrongWithLogN", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$a55f4d19f769a9aa79c8ec5350ab3a0ed5$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073__$a55f4d19f769a9aa79c8ec5350ab3a0ed5$__9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033", + "linkReferences": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 580 + } + ] + } + }, + "deployedLinkReferences": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "ZKTranscriptLib": [ + { + "length": 20, + "start": 360 + } + ] + } + }, + "immutableReferences": { + "7763": [ + { + "length": 32, + "start": 91 + }, + { + "length": 32, + "start": 148 + }, + { + "length": 32, + "start": 257 + }, + { + "length": 32, + "start": 466 + }, + { + "length": 32, + "start": 2608 + }, + { + "length": 32, + "start": 2877 + }, + { + "length": 32, + "start": 3036 + }, + { + "length": 32, + "start": 3082 + }, + { + "length": 32, + "start": 3216 + }, + { + "length": 32, + "start": 5412 + }, + { + "length": 32, + "start": 5587 + }, + { + "length": 32, + "start": 5638 + }, + { + "length": 32, + "start": 6160 + }, + { + "length": 32, + "start": 11154 + }, + { + "length": 32, + "start": 11963 + } + ], + "7765": [ + { + "length": 32, + "start": 398 + } + ], + "7767": [ + { + "length": 32, + "start": 432 + }, + { + "length": 32, + "start": 2306 + } + ] + }, + "inputSourceName": "project/contracts/verifiers/WithdrawVerifier.sol", + "buildInfoId": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifierLib.json b/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifierLib.json new file mode 100644 index 0000000..22f72f6 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/artifacts/withdrawVerifier#WithdrawVerifierLib.json @@ -0,0 +1,400 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "ZKTranscriptLib", + "sourceName": "contracts/verifiers/WithdrawVerifier.sol", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "Fr[16]", + "name": "pairingPointObject", + "type": "uint256[16]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w3", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "w4", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadCounts", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupReadTags", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "lookupInverses", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "zPerm", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[3]", + "name": "libraCommitments", + "type": "tuple[3]" + }, + { + "internalType": "Fr", + "name": "libraSum", + "type": "uint256" + }, + { + "internalType": "Fr[9][28]", + "name": "sumcheckUnivariates", + "type": "uint256[9][28]" + }, + { + "internalType": "Fr[41]", + "name": "sumcheckEvaluations", + "type": "uint256[41]" + }, + { + "internalType": "Fr", + "name": "libraEvaluation", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "geminiMaskingPoly", + "type": "tuple" + }, + { + "internalType": "Fr", + "name": "geminiMaskingEval", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point[27]", + "name": "geminiFoldComms", + "type": "tuple[27]" + }, + { + "internalType": "Fr[28]", + "name": "geminiAEvaluations", + "type": "uint256[28]" + }, + { + "internalType": "Fr[4]", + "name": "libraPolyEvals", + "type": "uint256[4]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "shplonkQ", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct Honk.G1Point", + "name": "kzgQuotient", + "type": "tuple" + } + ], + "internalType": "struct Honk.ZKProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "vkHash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicInputsSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "logN", + "type": "uint256" + } + ], + "name": "generateTranscript", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "Fr", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaTwo", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "etaThree", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "beta", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "gamma", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct Honk.RelationParameters", + "name": "relationParameters", + "type": "tuple" + }, + { + "internalType": "Fr[27]", + "name": "alphas", + "type": "uint256[27]" + }, + { + "internalType": "Fr[28]", + "name": "gateChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "libraChallenge", + "type": "uint256" + }, + { + "internalType": "Fr[28]", + "name": "sumCheckUChallenges", + "type": "uint256[28]" + }, + { + "internalType": "Fr", + "name": "rho", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "geminiR", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkNu", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "shplonkZ", + "type": "uint256" + }, + { + "internalType": "Fr", + "name": "publicInputsDelta", + "type": "uint256" + } + ], + "internalType": "struct ZKTranscript", + "name": "t", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033", + "deployedBytecode": "0x7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": {}, + "inputSourceName": "project/contracts/verifiers/WithdrawVerifier.sol", + "buildInfoId": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48" +} \ No newline at end of file diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json new file mode 100644 index 0000000..b82789e --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-20b5f0cd9000b7b014db665ddc42749fefec2d48", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/WithdrawVerifier.sol": "project/contracts/verifiers/WithdrawVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/WithdrawVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 4096;\nuint256 constant LOG_N = 12;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 32;\nuint256 constant VK_HASH = 0x12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(4096),\n logCircuitSize: uint256(12),\n publicInputsSize: uint256(32),\n ql: Honk.G1Point({ \n x: uint256(0x29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b3),\n y: uint256(0x074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d337)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf2),\n y: uint256(0x0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b8),\n y: uint256(0x2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b),\n y: uint256(0x058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d8),\n y: uint256(0x062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d),\n y: uint256(0x08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c08),\n y: uint256(0x2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf8),\n y: uint256(0x07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a4),\n y: uint256(0x05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c7),\n y: uint256(0x283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda),\n y: uint256(0x0005c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d6),\n y: uint256(0x193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c),\n y: uint256(0x158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f3),\n y: uint256(0x00ce217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba1)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca),\n y: uint256(0x22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca119)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b38),\n y: uint256(0x0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d),\n y: uint256(0x041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba2)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee),\n y: uint256(0x2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f8),\n y: uint256(0x2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f20),\n y: uint256(0x0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da019),\n y: uint256(0x13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe),\n y: uint256(0x1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba23)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e),\n y: uint256(0x04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract WithdrawVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json new file mode 100644 index 0000000..d0b011a --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-3fbdc73a9c11b1d9ad2f2fe1a3ec717e6ff0cfea", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/DepositVerifier.sol": "project/contracts/verifiers/DepositVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/DepositVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 256;\nuint256 constant LOG_N = 8;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 19;\nuint256 constant VK_HASH = 0x0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(256),\n logCircuitSize: uint256(8),\n publicInputsSize: uint256(19),\n ql: Honk.G1Point({ \n x: uint256(0x149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d55),\n y: uint256(0x0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d1)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f30174),\n y: uint256(0x29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e98)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d),\n y: uint256(0x21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad6)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c61),\n y: uint256(0x01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d3)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b),\n y: uint256(0x2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf14),\n y: uint256(0x05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0073e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b0),\n y: uint256(0x20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c036),\n y: uint256(0x02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e4)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e),\n y: uint256(0x04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af),\n y: uint256(0x1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be88),\n y: uint256(0x1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f79),\n y: uint256(0x05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c253),\n y: uint256(0x0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e5),\n y: uint256(0x050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d190)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e),\n y: uint256(0x2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d981)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc98887),\n y: uint256(0x1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec235625)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef),\n y: uint256(0x0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c4982)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf),\n y: uint256(0x1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da2)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac),\n y: uint256(0x0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f),\n y: uint256(0x198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a),\n y: uint256(0x0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a),\n y: uint256(0x22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b1),\n y: uint256(0x2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract DepositVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json new file mode 100644 index 0000000..0d287cc --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-8972d3a7f8108de5db8b67a6d475ea02713d2285", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/TransferVerifier.sol": "project/contracts/verifiers/TransferVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/TransferVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 16384;\nuint256 constant LOG_N = 14;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 23;\nuint256 constant VK_HASH = 0x1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(16384),\n logCircuitSize: uint256(14),\n publicInputsSize: uint256(23),\n ql: Honk.G1Point({ \n x: uint256(0x145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca),\n y: uint256(0x06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x0040a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b),\n y: uint256(0x165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f69),\n y: uint256(0x2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be),\n y: uint256(0x1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc),\n y: uint256(0x050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d),\n y: uint256(0x2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a991),\n y: uint256(0x286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df923)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e791),\n y: uint256(0x1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d4),\n y: uint256(0x035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb6)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c66),\n y: uint256(0x0037adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c3),\n y: uint256(0x175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f71),\n y: uint256(0x03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d6),\n y: uint256(0x20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a),\n y: uint256(0x19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a8)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af6),\n y: uint256(0x080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e),\n y: uint256(0x3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f048)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf),\n y: uint256(0x0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df313)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b),\n y: uint256(0x1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea2785)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f),\n y: uint256(0x0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d),\n y: uint256(0x04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf65),\n y: uint256(0x26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d9),\n y: uint256(0x18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f9),\n y: uint256(0x26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract TransferVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-ad0cc7caf95bc67952c9cdec84ad3dce5a76ea7e.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-ad0cc7caf95bc67952c9cdec84ad3dce5a76ea7e.json new file mode 100644 index 0000000..55e2502 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-ad0cc7caf95bc67952c9cdec84ad3dce5a76ea7e.json @@ -0,0 +1,54 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-ad0cc7caf95bc67952c9cdec84ad3dce5a76ea7e", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/mocks/AUDD.sol": "project/contracts/mocks/AUDD.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [ + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" + ] + }, + "sources": { + "npm/@openzeppelin/contracts@5.4.0/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * Both values are immutable: they can only be set once during construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /// @inheritdoc IERC20\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /// @inheritdoc IERC20\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /// @inheritdoc IERC20\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Skips emitting an {Approval} event indicating an allowance update. This is not\n * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n *\n * ```solidity\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance < type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "project/contracts/mocks/AUDD.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract AUDD is ERC20 {\n constructor() ERC20(\"AUDD\", \"AUDD\") {\n _mint(msg.sender, 1000 * 10 ** 6);\n }\n\n function decimals() public pure override returns (uint8) {\n return 6;\n }\n\n function mint(address _recipient, uint256 _amount) public {\n _mint(_recipient, _amount);\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-c8eaf1e731d163f064d4197bfb5b0c7e14f49296.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-c8eaf1e731d163f064d4197bfb5b0c7e14f49296.json new file mode 100644 index 0000000..ce2955b --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-c8eaf1e731d163f064d4197bfb5b0c7e14f49296.json @@ -0,0 +1,54 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-c8eaf1e731d163f064d4197bfb5b0c7e14f49296", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/mocks/USDC.sol": "project/contracts/mocks/USDC.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [ + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" + ] + }, + "sources": { + "npm/@openzeppelin/contracts@5.4.0/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * Both values are immutable: they can only be set once during construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /// @inheritdoc IERC20\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /// @inheritdoc IERC20\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /// @inheritdoc IERC20\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Skips emitting an {Approval} event indicating an allowance update. This is not\n * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n *\n * ```solidity\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance < type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "project/contracts/mocks/USDC.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract USDC is ERC20 {\n constructor() ERC20(\"USDC\", \"USDC\") {\n _mint(msg.sender, 1000 * 10 ** 6);\n }\n\n function decimals() public pure override returns (uint8) {\n return 6;\n }\n\n function mint(address _recipient, uint256 _amount) public {\n _mint(_recipient, _amount);\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-cd3964288f6c44135c197c8203659aefd819d931.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-cd3964288f6c44135c197c8203659aefd819d931.json new file mode 100644 index 0000000..eab8050 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-cd3964288f6c44135c197c8203659aefd819d931.json @@ -0,0 +1,54 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-cd3964288f6c44135c197c8203659aefd819d931", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/mocks/FourDEC.sol": "project/contracts/mocks/FourDEC.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [ + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" + ] + }, + "sources": { + "npm/@openzeppelin/contracts@5.4.0/interfaces/draft-IERC6093.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC20InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC20InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\n * @param needed Minimum amount required to perform a transfer.\n */\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC20InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n * @param spender Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n /**\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n * Used in balance queries.\n * @param owner Address of the current owner of a token.\n */\n error ERC721InvalidOwner(address owner);\n\n /**\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\n * @param tokenId Identifier number of a token.\n */\n error ERC721NonexistentToken(uint256 tokenId);\n\n /**\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param tokenId Identifier number of a token.\n * @param owner Address of the current owner of a token.\n */\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC721InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC721InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param tokenId Identifier number of a token.\n */\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC721InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n /**\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n * @param balance Current balance for the interacting account.\n * @param needed Minimum amount required to perform a transfer.\n * @param tokenId Identifier number of a token.\n */\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n /**\n * @dev Indicates a failure with the token `sender`. Used in transfers.\n * @param sender Address whose tokens are being transferred.\n */\n error ERC1155InvalidSender(address sender);\n\n /**\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\n * @param receiver Address to which tokens are being transferred.\n */\n error ERC1155InvalidReceiver(address receiver);\n\n /**\n * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n * @param owner Address of the current owner of a token.\n */\n error ERC1155MissingApprovalForAll(address operator, address owner);\n\n /**\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n * @param approver Address initiating an approval operation.\n */\n error ERC1155InvalidApprover(address approver);\n\n /**\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n * @param operator Address that may be allowed to operate on tokens without being their owner.\n */\n error ERC1155InvalidOperator(address operator);\n\n /**\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n * Used in batch transfers.\n * @param idsLength Length of the array of token identifiers\n * @param valuesLength Length of the array of token amounts\n */\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n mapping(address account => uint256) private _balances;\n\n mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * Both values are immutable: they can only be set once during construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return 18;\n }\n\n /// @inheritdoc IERC20\n function totalSupply() public view virtual returns (uint256) {\n return _totalSupply;\n }\n\n /// @inheritdoc IERC20\n function balanceOf(address account) public view virtual returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `value`.\n */\n function transfer(address to, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, value);\n return true;\n }\n\n /// @inheritdoc IERC20\n function allowance(address owner, address spender) public view virtual returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 value) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Skips emitting an {Approval} event indicating an allowance update. This is not\n * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `value`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `value`.\n */\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, value);\n _transfer(from, to, value);\n return true;\n }\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _transfer(address from, address to, uint256 value) internal {\n if (from == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n if (to == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(from, to, value);\n }\n\n /**\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n * this function.\n *\n * Emits a {Transfer} event.\n */\n function _update(address from, address to, uint256 value) internal virtual {\n if (from == address(0)) {\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\n _totalSupply += value;\n } else {\n uint256 fromBalance = _balances[from];\n if (fromBalance < value) {\n revert ERC20InsufficientBalance(from, fromBalance, value);\n }\n unchecked {\n // Overflow not possible: value <= fromBalance <= totalSupply.\n _balances[from] = fromBalance - value;\n }\n }\n\n if (to == address(0)) {\n unchecked {\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n _totalSupply -= value;\n }\n } else {\n unchecked {\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n _balances[to] += value;\n }\n }\n\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n * Relies on the `_update` mechanism\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead.\n */\n function _mint(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidReceiver(address(0));\n }\n _update(address(0), account, value);\n }\n\n /**\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n * Relies on the `_update` mechanism.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * NOTE: This function is not virtual, {_update} should be overridden instead\n */\n function _burn(address account, uint256 value) internal {\n if (account == address(0)) {\n revert ERC20InvalidSender(address(0));\n }\n _update(account, address(0), value);\n }\n\n /**\n * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n *\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n _approve(owner, spender, value, true);\n }\n\n /**\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n *\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n * `Approval` event during `transferFrom` operations.\n *\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n * true using the following override:\n *\n * ```solidity\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n * super._approve(owner, spender, value, true);\n * }\n * ```\n *\n * Requirements are the same as {_approve}.\n */\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n if (owner == address(0)) {\n revert ERC20InvalidApprover(address(0));\n }\n if (spender == address(0)) {\n revert ERC20InvalidSpender(address(0));\n }\n _allowances[owner][spender] = value;\n if (emitEvent) {\n emit Approval(owner, spender, value);\n }\n }\n\n /**\n * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n *\n * Does not update the allowance value in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Does not emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance < type(uint256).max) {\n if (currentAllowance < value) {\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n }\n unchecked {\n _approve(owner, spender, currentAllowance - value, false);\n }\n }\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "project/contracts/mocks/FourDEC.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract FourDEC is ERC20 {\n constructor() ERC20(\"FourDEC\", \"FourDEC\") {\n _mint(msg.sender, 1000 * 10 ** 4);\n }\n\n function decimals() public pure override returns (uint8) {\n return 4;\n }\n\n function mint(address _recipient, uint256 _amount) public {\n _mint(_recipient, _amount);\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json new file mode 100644 index 0000000..a73304c --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52.json @@ -0,0 +1,37 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-e4258ba9617742ad3b101066a24619cb45efae52", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/verifiers/TransferExternalVerifier.sol": "project/contracts/verifiers/TransferExternalVerifier.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/verifiers/TransferExternalVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 16384;\nuint256 constant LOG_N = 14;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 35;\nuint256 constant VK_HASH = 0x0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a2988;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(16384),\n logCircuitSize: uint256(14),\n publicInputsSize: uint256(35),\n ql: Honk.G1Point({ \n x: uint256(0x282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db746),\n y: uint256(0x0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb746656)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a),\n y: uint256(0x147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b2),\n y: uint256(0x15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d),\n y: uint256(0x207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d9),\n y: uint256(0x2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb),\n y: uint256(0x1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf0),\n y: uint256(0x299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb23),\n y: uint256(0x0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a349160)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a),\n y: uint256(0x0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d95)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca),\n y: uint256(0x16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d),\n y: uint256(0x187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f46)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f112),\n y: uint256(0x30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b43),\n y: uint256(0x26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a),\n y: uint256(0x1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f824)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa),\n y: uint256(0x27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a3),\n y: uint256(0x049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c170773895124),\n y: uint256(0x01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c86)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d03),\n y: uint256(0x20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba665792934)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c76),\n y: uint256(0x035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e),\n y: uint256(0x25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c88),\n y: uint256(0x2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f581),\n y: uint256(0x0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e9)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d),\n y: uint256(0x1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract TransferExternalVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json new file mode 100644 index 0000000..52c13ac --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/build-info/solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838.json @@ -0,0 +1,64 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_28-fef4b5630deb701627d1120a176010d0d64c6838", + "solcVersion": "0.8.28", + "solcLongVersion": "0.8.28+commit.7893614a", + "userSourceNameMap": { + "contracts/CommBankDotEth.sol": "project/contracts/CommBankDotEth.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [ + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/", + "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" + ] + }, + "sources": { + "npm/@openzeppelin/contracts@5.4.0/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {IERC165, ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address account => bool) hasRole;\n bytes32 adminRole;\n }\n\n mapping(bytes32 role => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with an {AccessControlUnauthorizedAccount} error including the required role.\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n return _roles[role].hasRole[account];\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n * is missing `role`.\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert AccessControlUnauthorizedAccount(account, role);\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n if (callerConfirmation != _msgSender()) {\n revert AccessControlBadConfirmation();\n }\n\n _revokeRole(role, callerConfirmation);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n if (!hasRole(role, account)) {\n _roles[role].hasRole[account] = true;\n emit RoleGranted(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n if (hasRole(role, account)) {\n _roles[role].hasRole[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev The `account` is missing a role.\n */\n error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n /**\n * @dev The caller of a function is not the expected one.\n *\n * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n */\n error AccessControlBadConfirmation();\n\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted to signal this.\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n */\n function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "npm/@openzeppelin/contracts@5.4.0/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "project/contracts/CommBankDotEth.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\nimport \"./PoseidonMerkleTree.sol\";\nimport {IVerifier} from \"./verifiers/DepositVerifier.sol\";\n\n// ___. __ __ .__\n// ____ ____ _____ _____\\_ |__ _____ ____ | | __ _____/ |_| |__\n// _/ ___\\/ _ \\ / \\ / \\| __ \\\\__ \\ / \\| |/ / _/ __ \\ __\\ | \\\n// \\ \\__( <_> ) Y Y \\ Y Y \\ \\_\\ \\/ __ \\| | \\ < \\ ___/| | | Y \\\n// \\___ >____/|__|_| /__|_| /___ (____ /___| /__|_ \\ /\\ \\___ >__| |___| /\n// \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/\n//\ncontract CommBankDotEth is PoseidonMerkleTree, AccessControl {\n address public depositVerifier;\n address public transferVerifier;\n address public withdrawVerifier;\n address public transferExternalVerifier;\n\n mapping(bytes32 => bool) public nullifierUsed;\n\n bytes32 public DEPOSIT_ROLE = keccak256(\"DEPOSIT_ROLE\");\n\n event NullifierUsed(bytes32 indexed nullifier);\n event NotePayload(bytes encryptedNote);\n\n uint256 constant NOTES_INPUT_LENGTH = 3;\n uint256 constant EXIT_ASSET_START_INDEX = 4;\n uint256 constant EXIT_AMOUNT_START_INDEX = 7;\n uint256 constant EXIT_ADDRESSES_START_INDEX = 10;\n\n address public immutable ETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n constructor(\n address _noteVerifier,\n address _transactVerifier,\n address _withdrawalVerifier,\n address _transferExternalVerifier\n ) PoseidonMerkleTree(12) {\n depositVerifier = _noteVerifier;\n transferVerifier = _transactVerifier;\n withdrawVerifier = _withdrawalVerifier;\n transferExternalVerifier = _transferExternalVerifier;\n\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _grantRole(DEPOSIT_ROLE, msg.sender);\n }\n\n function deposit(\n address _erc20,\n uint256 _amount, // with decimals\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public onlyRole(DEPOSIT_ROLE) {\n bool depositTransfer = IERC20(_erc20).transferFrom(\n msg.sender,\n address(this),\n _amount\n );\n require(depositTransfer, \"failed to transfer deposit\");\n\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check input input asset address and amount match proof inputs\n require(\n _erc20 == address(uint160(uint256(_publicInputs[1]))),\n \"ERC20 address mismatch\"\n );\n require(\n _amount == uint64(uint256(_publicInputs[2])),\n \"Address amount incorrect\"\n );\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function depositNative(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload // TODO this probably doesn't need to be an array\n ) public payable onlyRole(DEPOSIT_ROLE) {\n // verify proof\n bool isValidProof = IVerifier(depositVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid deposit proof!\");\n\n // check that input address is 0xEee address\n require(\n ETH_ADDRESS == address(uint160(uint256(_publicInputs[1]))),\n \"Address mismatch\"\n );\n // check that msg.value matches amount in proof\n require(msg.value == uint64(uint256(_publicInputs[2])), \"Amount incorrect\");\n\n // insert note\n _insert(uint256(_publicInputs[0]));\n\n // TODO this probably doesn't need to be a loop\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function transfer(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer proof\");\n\n // if proof is valid, write nullifiers as spent\n for (uint256 i = 1; i < NOTES_INPUT_LENGTH + 1; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // and insert output notes\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // emit payload note parameters\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n\n function withdraw(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs\n ) public {\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n bool isValidProof = IVerifier(withdrawVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid withdraw proof\");\n\n // Mark nullifiers as spent\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n // check not spent\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n // mark as spent\n nullifierUsed[_publicInputs[i]] = true;\n\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process withdrawals\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = EXIT_ASSET_START_INDEX + i;\n uint256 amountIndex = EXIT_AMOUNT_START_INDEX + i;\n uint256 addressIndex = EXIT_ADDRESSES_START_INDEX + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0) {\n if (exitAsset == ETH_ADDRESS) {\n // if it's eth, send the amount of eth to them\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n // Transfer tokens to the exit address\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n }\n\n // transfer function that allows for arbitrary amounts of withdrawal (not just note based)\n function transferExternal(\n bytes calldata _proof,\n bytes32[] calldata _publicInputs,\n bytes[] calldata _payload\n ) public {\n // verify the root is in the trees history\n require(isKnownRoot(uint256(_publicInputs[0])), \"Invalid Root!\");\n\n // verify the proof\n bool isValidProof = IVerifier(transferExternalVerifier).verify(\n _proof,\n _publicInputs\n );\n require(isValidProof, \"Invalid transfer external proof\");\n\n // Mark nullifiers as spent (indices 1-3)\n for (uint256 i = 1; i <= NOTES_INPUT_LENGTH; i++) {\n if (_publicInputs[i] != bytes32(0)) {\n require(\n nullifierUsed[_publicInputs[i]] == false,\n \"Nullifier already spent\"\n );\n nullifierUsed[_publicInputs[i]] = true;\n emit NullifierUsed(_publicInputs[i]);\n }\n }\n\n // Process output notes (indices 4-6 are output_hashes)\n // Insert internal transfer notes into merkle tree\n for (\n uint256 i = NOTES_INPUT_LENGTH + 1;\n i < NOTES_INPUT_LENGTH + 1 + NOTES_INPUT_LENGTH;\n i++\n ) {\n if (_publicInputs[i] != bytes32(0)) {\n _insert(uint256(_publicInputs[i]));\n }\n }\n\n // Process external withdrawals (indices 7-9: exit_assets, 10-12: exit_amounts, 13-15: exit_addresses)\n uint256 exitAssetStartIndex = 7;\n uint256 exitAmountStartIndex = exitAssetStartIndex + NOTES_INPUT_LENGTH;\n uint256 exitAddressStartIndex = exitAmountStartIndex + NOTES_INPUT_LENGTH;\n\n for (uint256 i = 0; i < NOTES_INPUT_LENGTH; i++) {\n uint256 assetIndex = exitAssetStartIndex + i;\n uint256 amountIndex = exitAmountStartIndex + i;\n uint256 addressIndex = exitAddressStartIndex + i;\n\n address exitAsset = address(uint160(uint256(_publicInputs[assetIndex])));\n uint256 exitAmount = uint256(_publicInputs[amountIndex]);\n address exitAddress = address(\n uint160(uint256(_publicInputs[addressIndex]))\n );\n\n if (exitAmount > 0 && exitAddress != address(0)) {\n if (exitAsset == ETH_ADDRESS) {\n require(\n address(this).balance >= exitAmount,\n \"Insufficient ETH balance\"\n );\n (bool success, ) = exitAddress.call{value: exitAmount}(\"\");\n require(success, \"ETH transfer failed\");\n } else {\n bool success = IERC20(exitAsset).transfer(exitAddress, exitAmount);\n require(success, \"Token transfer failed\");\n }\n }\n }\n\n // Emit payload note parameters for internal transfers\n for (uint256 i = 0; i < 3 && i < _payload.length; i++) {\n if (_payload[i].length != 0) {\n emit NotePayload(_payload[i]);\n }\n }\n }\n}\n" + }, + "project/contracts/PoseidonMerkleTree.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.24;\n\ncontract PoseidonMerkleTree {\n // The root of a poseidon2 merkle tree with height 12 and all leaf nodes filled with:\n // EMPTY_LEAF = keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n uint256 public constant INITIAL_ROOT =\n 0x124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f;\n\n // The maximum field element in BN254\n uint256 public constant PRIME =\n 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;\n\n // filledSubtrees and roots could be bytes32[size], but using mappings makes it cheaper because\n // it removes index range check on every interaction\n mapping(uint256 => uint256) public filledSubtrees;\n mapping(uint256 => uint256) public roots;\n\n uint256 public immutable height; // 12\n\n uint32 public constant ROOT_HISTORY_SIZE = 100;\n uint32 public currentRootIndex = 0;\n uint256 public nextIndex = 0;\n\n uint256 public MAX_LEAF_INDEX;\n\n address public poseidon2Hasher;\n address public deployer;\n\n constructor(uint256 _height) {\n height = _height;\n MAX_LEAF_INDEX = 2 ** (_height - 1);\n\n roots[0] = uint256(INITIAL_ROOT);\n\n deployer = msg.sender;\n }\n\n // TODO make this better\n function setPoseidon(address _hasher) public {\n require(poseidon2Hasher == address(0), \"Can't set it twice!\");\n require(msg.sender == deployer, \"only deployer can set poseidon\");\n poseidon2Hasher = _hasher;\n }\n\n function zeros(uint256 i) public pure returns (uint256) {\n if (i == 0) {\n // Base ZERO_VALUE: keccak256(abi.encodePacked(\"TANGERINE\")) % FIELD_MODULUS\n return\n uint256(\n 0x1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478\n );\n } else if (i == 1) {\n return\n uint256(\n 0x2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105\n );\n } else if (i == 2) {\n return\n uint256(\n 0x237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445\n );\n } else if (i == 3) {\n return\n uint256(\n 0x0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c\n );\n } else if (i == 4) {\n return\n uint256(\n 0x0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3\n );\n } else if (i == 5) {\n return\n uint256(\n 0x235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd\n );\n } else if (i == 6) {\n return\n uint256(\n 0x1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264\n );\n } else if (i == 7) {\n return\n uint256(\n 0x09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976\n );\n } else if (i == 8) {\n return\n uint256(\n 0x2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18\n );\n } else if (i == 9) {\n return\n uint256(\n 0x0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f\n );\n } else if (i == 10) {\n return\n uint256(\n 0x181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b\n );\n } else {\n revert(\"Index out of bounds\");\n }\n }\n\n event LeafInserted(uint256 indexed leafIndex, bytes32 indexed leafValue);\n\n // Add a helper function to generate consistent keys\n function getStorageKey(\n uint256 level,\n uint256 index\n ) internal pure returns (uint256) {\n return (level << 32) | index; // Combine level and index into a single key\n }\n\n function _insert(uint256 _leaf) internal returns (uint256 index) {\n uint256 insertIndex = nextIndex;\n require(insertIndex != MAX_LEAF_INDEX, \"Tree Full\");\n\n uint256 currentIndex = insertIndex;\n uint256 currentHash = _leaf;\n\n // Store leaf at level 0\n filledSubtrees[getStorageKey(0, currentIndex)] = currentHash;\n\n for (uint256 i = 0; i < height - 1; i++) {\n bool isLeft = currentIndex % 2 == 0;\n uint256 siblingIndex = isLeft ? currentIndex + 1 : currentIndex - 1;\n\n // Get sibling value using consistent key generation\n uint256 siblingKey = getStorageKey(i, siblingIndex);\n uint256 sibling = filledSubtrees[siblingKey];\n if (sibling == 0) {\n sibling = zeros(i);\n }\n\n // Calculate parent hash based on position\n if (isLeft) {\n currentHash = hashLeftRight(currentHash, sibling);\n } else {\n currentHash = hashLeftRight(sibling, currentHash);\n }\n\n // Move up to parent level\n currentIndex = currentIndex / 2;\n\n // Store the computed hash for the next level using consistent key\n filledSubtrees[getStorageKey(i + 1, currentIndex)] = currentHash;\n }\n\n uint32 newRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;\n currentRootIndex = newRootIndex;\n roots[newRootIndex] = currentHash;\n\n nextIndex = insertIndex + 1;\n emit LeafInserted(insertIndex, bytes32(_leaf));\n\n return insertIndex;\n }\n\n function hashLeftRight(\n uint256 _left,\n uint256 _right\n ) public view returns (uint256) {\n // Encode two uint256 values as calldata for Poseidon2Yul\n bytes memory callData = abi.encode(_left, _right);\n\n // Call the Poseidon2Yul fallback function\n (bool success, bytes memory result) = poseidon2Hasher.staticcall(callData);\n require(success, \"Poseidon2 hash failed\");\n\n // Decode the result as uint256\n return abi.decode(result, (uint256));\n }\n\n function isKnownRoot(uint256 _root) public view returns (bool) {\n if (_root == 0) {\n return false;\n }\n uint32 _currentRootIndex = currentRootIndex;\n uint32 i = _currentRootIndex;\n do {\n if (_root == roots[i]) {\n return true;\n }\n if (i == 0) {\n i = ROOT_HISTORY_SIZE;\n }\n i--;\n } while (i != _currentRootIndex);\n return false;\n }\n}\n" + }, + "project/contracts/verifiers/DepositVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2022 Aztec\npragma solidity >=0.8.21;\n\nuint256 constant N = 256;\nuint256 constant LOG_N = 8;\nuint256 constant NUMBER_OF_PUBLIC_INPUTS = 19;\nuint256 constant VK_HASH = 0x0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b;\nlibrary HonkVerificationKey {\n function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n Honk.VerificationKey memory vk = Honk.VerificationKey({\n circuitSize: uint256(256),\n logCircuitSize: uint256(8),\n publicInputsSize: uint256(19),\n ql: Honk.G1Point({ \n x: uint256(0x149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d55),\n y: uint256(0x0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d1)\n }),\n qr: Honk.G1Point({ \n x: uint256(0x1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f30174),\n y: uint256(0x29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e98)\n }),\n qo: Honk.G1Point({ \n x: uint256(0x2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d),\n y: uint256(0x21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad6)\n }),\n q4: Honk.G1Point({ \n x: uint256(0x01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c61),\n y: uint256(0x01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d3)\n }),\n qm: Honk.G1Point({ \n x: uint256(0x0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b),\n y: uint256(0x2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2)\n }),\n qc: Honk.G1Point({ \n x: uint256(0x27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf14),\n y: uint256(0x05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23)\n }),\n qLookup: Honk.G1Point({ \n x: uint256(0x0073e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b0),\n y: uint256(0x20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d)\n }),\n qArith: Honk.G1Point({ \n x: uint256(0x21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c036),\n y: uint256(0x02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e4)\n }),\n qDeltaRange: Honk.G1Point({ \n x: uint256(0x2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e),\n y: uint256(0x04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c)\n }),\n qElliptic: Honk.G1Point({ \n x: uint256(0x13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af),\n y: uint256(0x1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df)\n }),\n qMemory: Honk.G1Point({ \n x: uint256(0x0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be88),\n y: uint256(0x1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa)\n }),\n qNnf: Honk.G1Point({ \n x: uint256(0x1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f79),\n y: uint256(0x05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9)\n }),\n qPoseidon2External: Honk.G1Point({ \n x: uint256(0x231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c253),\n y: uint256(0x0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137)\n }),\n qPoseidon2Internal: Honk.G1Point({ \n x: uint256(0x090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e5),\n y: uint256(0x050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d190)\n }),\n s1: Honk.G1Point({ \n x: uint256(0x0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e),\n y: uint256(0x2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d981)\n }),\n s2: Honk.G1Point({ \n x: uint256(0x2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc98887),\n y: uint256(0x1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec235625)\n }),\n s3: Honk.G1Point({ \n x: uint256(0x0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef),\n y: uint256(0x0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c4982)\n }),\n s4: Honk.G1Point({ \n x: uint256(0x16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf),\n y: uint256(0x1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da2)\n }),\n t1: Honk.G1Point({ \n x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),\n y: uint256(0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f)\n }),\n t2: Honk.G1Point({ \n x: uint256(0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e),\n y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)\n }),\n t3: Honk.G1Point({ \n x: uint256(0x13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a77),\n y: uint256(0x0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d7)\n }),\n t4: Honk.G1Point({ \n x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),\n y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)\n }),\n id1: Honk.G1Point({ \n x: uint256(0x14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac),\n y: uint256(0x0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3)\n }),\n id2: Honk.G1Point({ \n x: uint256(0x2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f),\n y: uint256(0x198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186)\n }),\n id3: Honk.G1Point({ \n x: uint256(0x29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a),\n y: uint256(0x0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e)\n }),\n id4: Honk.G1Point({ \n x: uint256(0x20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a),\n y: uint256(0x22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d)\n }),\n lagrangeFirst: Honk.G1Point({ \n x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),\n y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)\n }),\n lagrangeLast: Honk.G1Point({ \n x: uint256(0x17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b1),\n y: uint256(0x2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5)\n })\n });\n return vk;\n }\n}\n\npragma solidity ^0.8.27;\n\ninterface IVerifier {\n function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);\n}\n\ntype Fr is uint256;\n\nusing {add as +} for Fr global;\nusing {sub as -} for Fr global;\nusing {mul as *} for Fr global;\n\nusing {exp as ^} for Fr global;\nusing {notEqual as !=} for Fr global;\nusing {equal as ==} for Fr global;\n\nuint256 constant SUBGROUP_SIZE = 256;\nuint256 constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Prime field order\nuint256 constant P = MODULUS;\nFr constant SUBGROUP_GENERATOR = Fr.wrap(0x07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76);\nFr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6);\nFr constant MINUS_ONE = Fr.wrap(MODULUS - 1);\nFr constant ONE = Fr.wrap(1);\nFr constant ZERO = Fr.wrap(0);\n// Instantiation\n\nlibrary FrLib {\n function from(uint256 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(value % MODULUS);\n }\n }\n\n function fromBytes32(bytes32 value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(uint256(value) % MODULUS);\n }\n }\n\n function toBytes32(Fr value) internal pure returns (bytes32) {\n unchecked {\n return bytes32(Fr.unwrap(value));\n }\n }\n\n function invert(Fr value) internal view returns (Fr) {\n uint256 v = Fr.unwrap(value);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), v)\n mstore(add(free, 0x80), sub(MODULUS, 2)) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function pow(Fr base, uint256 v) internal view returns (Fr) {\n uint256 b = Fr.unwrap(base);\n uint256 result;\n\n // Call the modexp precompile to invert in the field\n assembly {\n let free := mload(0x40)\n mstore(free, 0x20)\n mstore(add(free, 0x20), 0x20)\n mstore(add(free, 0x40), 0x20)\n mstore(add(free, 0x60), b)\n mstore(add(free, 0x80), v) \n mstore(add(free, 0xa0), MODULUS)\n let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)\n if iszero(success) {\n revert(0, 0)\n }\n result := mload(0x00)\n mstore(0x40, add(free, 0x80))\n }\n\n return Fr.wrap(result);\n }\n\n function div(Fr numerator, Fr denominator) internal view returns (Fr) {\n unchecked {\n return numerator * invert(denominator);\n }\n }\n\n function sqr(Fr value) internal pure returns (Fr) {\n unchecked {\n return value * value;\n }\n }\n\n function unwrap(Fr value) internal pure returns (uint256) {\n unchecked {\n return Fr.unwrap(value);\n }\n }\n\n function neg(Fr value) internal pure returns (Fr) {\n unchecked {\n return Fr.wrap(MODULUS - Fr.unwrap(value));\n }\n }\n}\n\n// Free functions\nfunction add(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction mul(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(mulmod(Fr.unwrap(a), Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction sub(Fr a, Fr b) pure returns (Fr) {\n unchecked {\n return Fr.wrap(addmod(Fr.unwrap(a), MODULUS - Fr.unwrap(b), MODULUS));\n }\n}\n\nfunction exp(Fr base, Fr exponent) pure returns (Fr) {\n if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);\n // Implement exponent with a loop as we will overflow otherwise\n for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {\n base = base * base;\n }\n return base;\n}\n\nfunction notEqual(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) != Fr.unwrap(b);\n }\n}\n\nfunction equal(Fr a, Fr b) pure returns (bool) {\n unchecked {\n return Fr.unwrap(a) == Fr.unwrap(b);\n }\n}\n\nuint256 constant CONST_PROOF_SIZE_LOG_N = 28;\n\nuint256 constant NUMBER_OF_SUBRELATIONS = 28;\nuint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;\nuint256 constant ZK_BATCHED_RELATION_PARTIAL_LENGTH = 9;\nuint256 constant NUMBER_OF_ENTITIES = 41;\nuint256 constant NUMBER_UNSHIFTED = 36;\nuint256 constant NUMBER_TO_BE_SHIFTED = 5;\nuint256 constant PAIRING_POINTS_SIZE = 16;\n\nuint256 constant FIELD_ELEMENT_SIZE = 0x20;\nuint256 constant GROUP_ELEMENT_SIZE = 0x40;\n\n// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1\nuint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;\n\n// ENUM FOR WIRES\nenum WIRE {\n Q_M,\n Q_C,\n Q_L,\n Q_R,\n Q_O,\n Q_4,\n Q_LOOKUP,\n Q_ARITH,\n Q_RANGE,\n Q_ELLIPTIC,\n Q_MEMORY,\n Q_NNF,\n Q_POSEIDON2_EXTERNAL,\n Q_POSEIDON2_INTERNAL,\n SIGMA_1,\n SIGMA_2,\n SIGMA_3,\n SIGMA_4,\n ID_1,\n ID_2,\n ID_3,\n ID_4,\n TABLE_1,\n TABLE_2,\n TABLE_3,\n TABLE_4,\n LAGRANGE_FIRST,\n LAGRANGE_LAST,\n W_L,\n W_R,\n W_O,\n W_4,\n Z_PERM,\n LOOKUP_INVERSES,\n LOOKUP_READ_COUNTS,\n LOOKUP_READ_TAGS,\n W_L_SHIFT,\n W_R_SHIFT,\n W_O_SHIFT,\n W_4_SHIFT,\n Z_PERM_SHIFT\n}\n\nlibrary Honk {\n struct G1Point {\n uint256 x;\n uint256 y;\n }\n\n struct VerificationKey {\n // Misc Params\n uint256 circuitSize;\n uint256 logCircuitSize;\n uint256 publicInputsSize;\n // Selectors\n G1Point qm;\n G1Point qc;\n G1Point ql;\n G1Point qr;\n G1Point qo;\n G1Point q4;\n G1Point qLookup; // Lookup\n G1Point qArith; // Arithmetic widget\n G1Point qDeltaRange; // Delta Range sort\n G1Point qMemory; // Memory\n G1Point qNnf; // Non-native Field\n G1Point qElliptic; // Auxillary\n G1Point qPoseidon2External;\n G1Point qPoseidon2Internal;\n // Copy cnstraints\n G1Point s1;\n G1Point s2;\n G1Point s3;\n G1Point s4;\n // Copy identity\n G1Point id1;\n G1Point id2;\n G1Point id3;\n G1Point id4;\n // Precomputed lookup table\n G1Point t1;\n G1Point t2;\n G1Point t3;\n G1Point t4;\n // Fixed first and last\n G1Point lagrangeFirst;\n G1Point lagrangeLast;\n }\n\n struct RelationParameters {\n // challenges\n Fr eta;\n Fr etaTwo;\n Fr etaThree;\n Fr beta;\n Fr gamma;\n // derived\n Fr publicInputsDelta;\n }\n\n struct Proof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Free wires\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Lookup helpers - Permutations\n G1Point zPerm;\n // Lookup helpers - logup\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Sumcheck\n Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n\n struct ZKProof {\n // Pairing point object\n Fr[PAIRING_POINTS_SIZE] pairingPointObject;\n // Commitments to wire polynomials\n G1Point w1;\n G1Point w2;\n G1Point w3;\n G1Point w4;\n // Commitments to logup witness polynomials\n G1Point lookupReadCounts;\n G1Point lookupReadTags;\n G1Point lookupInverses;\n // Commitment to grand permutation polynomial\n G1Point zPerm;\n G1Point[3] libraCommitments;\n // Sumcheck\n Fr libraSum;\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates;\n Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations;\n Fr libraEvaluation;\n // ZK\n G1Point geminiMaskingPoly;\n Fr geminiMaskingEval;\n // Shplemini\n G1Point[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms;\n Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations;\n Fr[4] libraPolyEvals;\n G1Point shplonkQ;\n G1Point kzgQuotient;\n }\n}\n\n// ZKTranscript library to generate fiat shamir challenges, the ZK transcript only differest\nstruct ZKTranscript {\n // Oink\n Honk.RelationParameters relationParameters;\n Fr[NUMBER_OF_ALPHAS] alphas;\n Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges;\n // Sumcheck\n Fr libraChallenge;\n Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges;\n // Shplemini\n Fr rho;\n Fr geminiR;\n Fr shplonkNu;\n Fr shplonkZ;\n // Derived\n Fr publicInputsDelta;\n}\n\nlibrary ZKTranscriptLib {\n function generateTranscript(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n uint256 logN\n ) external pure returns (ZKTranscript memory t) {\n Fr previousChallenge;\n (t.relationParameters, previousChallenge) =\n generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);\n\n (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof);\n\n (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge, logN);\n (t.libraChallenge, previousChallenge) = generateLibraChallenge(previousChallenge, proof);\n (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge, logN);\n\n (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge);\n\n (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge, logN);\n\n (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge, logN);\n\n (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge);\n return t;\n }\n\n function splitChallenge(Fr challenge) internal pure returns (Fr first, Fr second) {\n uint256 challengeU256 = uint256(Fr.unwrap(challenge));\n uint256 lo = challengeU256 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 hi = challengeU256 >> 128;\n first = FrLib.fromBytes32(bytes32(lo));\n second = FrLib.fromBytes32(bytes32(hi));\n }\n\n function generateRelationParametersChallenges(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize,\n Fr previousChallenge\n ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {\n (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) =\n generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);\n\n (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof);\n }\n\n function generateEtaChallenge(\n Honk.ZKProof memory proof,\n bytes32[] calldata publicInputs,\n uint256 vkHash,\n uint256 publicInputsSize\n ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) {\n bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);\n round0[0] = bytes32(vkHash);\n\n for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {\n round0[1 + i] = bytes32(publicInputs[i]);\n }\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);\n }\n\n // Create the first challenge\n // Note: w4 is added to the challenge later on\n round0[1 + publicInputsSize] = bytes32(proof.w1.x);\n round0[1 + publicInputsSize + 1] = bytes32(proof.w1.y);\n round0[1 + publicInputsSize + 2] = bytes32(proof.w2.x);\n round0[1 + publicInputsSize + 3] = bytes32(proof.w2.y);\n round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);\n round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);\n\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0)));\n (eta, etaTwo) = splitChallenge(previousChallenge);\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n\n (etaThree,) = splitChallenge(previousChallenge);\n }\n\n function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)\n {\n bytes32[7] memory round1;\n round1[0] = FrLib.toBytes32(previousChallenge);\n round1[1] = bytes32(proof.lookupReadCounts.x);\n round1[2] = bytes32(proof.lookupReadCounts.y);\n round1[3] = bytes32(proof.lookupReadTags.x);\n round1[4] = bytes32(proof.lookupReadTags.y);\n round1[5] = bytes32(proof.w4.x);\n round1[6] = bytes32(proof.w4.y);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round1)));\n (beta, gamma) = splitChallenge(nextPreviousChallenge);\n }\n\n // Alpha challenges non-linearise the gate contributions\n function generateAlphaChallenges(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge)\n {\n // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup\n uint256[5] memory alpha0;\n alpha0[0] = Fr.unwrap(previousChallenge);\n alpha0[1] = proof.lookupInverses.x;\n alpha0[2] = proof.lookupInverses.y;\n alpha0[3] = proof.zPerm.x;\n alpha0[4] = proof.zPerm.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(alpha0)));\n Fr alpha;\n (alpha,) = splitChallenge(nextPreviousChallenge);\n\n // Compute powers of alpha for batching subrelations\n alphas[0] = alpha;\n for (uint256 i = 1; i < NUMBER_OF_ALPHAS; i++) {\n alphas[i] = alphas[i - 1] * alpha;\n }\n }\n\n function generateGateChallenges(Fr previousChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)\n {\n previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));\n (gateChallenges[0],) = splitChallenge(previousChallenge);\n for (uint256 i = 1; i < logN; i++) {\n gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];\n }\n nextPreviousChallenge = previousChallenge;\n }\n\n function generateLibraChallenge(Fr previousChallenge, Honk.ZKProof memory proof)\n internal\n pure\n returns (Fr libraChallenge, Fr nextPreviousChallenge)\n {\n // 2 comm, 1 sum, 1 challenge\n uint256[4] memory challengeData;\n challengeData[0] = Fr.unwrap(previousChallenge);\n challengeData[1] = proof.libraCommitments[0].x;\n challengeData[2] = proof.libraCommitments[0].y;\n challengeData[3] = Fr.unwrap(proof.libraSum);\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(challengeData)));\n (libraChallenge,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateSumcheckChallenges(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge)\n {\n for (uint256 i = 0; i < logN; i++) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH + 1] memory univariateChal;\n univariateChal[0] = prevChallenge;\n\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];\n }\n prevChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(univariateChal)));\n\n (sumcheckChallenges[i],) = splitChallenge(prevChallenge);\n }\n nextPreviousChallenge = prevChallenge;\n }\n\n // We add Libra claimed eval + 3 comm + 1 more eval\n function generateRhoChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr rho, Fr nextPreviousChallenge)\n {\n uint256[NUMBER_OF_ENTITIES + 9] memory rhoChallengeElements;\n rhoChallengeElements[0] = Fr.unwrap(prevChallenge);\n uint256 i;\n for (i = 1; i <= NUMBER_OF_ENTITIES; i++) {\n rhoChallengeElements[i] = Fr.unwrap(proof.sumcheckEvaluations[i - 1]);\n }\n rhoChallengeElements[i] = Fr.unwrap(proof.libraEvaluation);\n\n i += 1;\n rhoChallengeElements[i] = proof.libraCommitments[1].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[1].y;\n i += 2;\n rhoChallengeElements[i] = proof.libraCommitments[2].x;\n rhoChallengeElements[i + 1] = proof.libraCommitments[2].y;\n i += 2;\n rhoChallengeElements[i] = proof.geminiMaskingPoly.x;\n rhoChallengeElements[i + 1] = proof.geminiMaskingPoly.y;\n\n i += 2;\n rhoChallengeElements[i] = Fr.unwrap(proof.geminiMaskingEval);\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(rhoChallengeElements)));\n (rho,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateGeminiRChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr geminiR, Fr nextPreviousChallenge)\n {\n uint256[] memory gR = new uint256[]((logN - 1) * 2 + 1);\n gR[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 0; i < logN - 1; i++) {\n gR[1 + i * 2] = proof.geminiFoldComms[i].x;\n gR[2 + i * 2] = proof.geminiFoldComms[i].y;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR)));\n\n (geminiR,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkNuChallenge(Honk.ZKProof memory proof, Fr prevChallenge, uint256 logN)\n internal\n pure\n returns (Fr shplonkNu, Fr nextPreviousChallenge)\n {\n uint256[] memory shplonkNuChallengeElements = new uint256[](logN + 1 + 4);\n shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n for (uint256 i = 1; i <= logN; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.geminiAEvaluations[i - 1]);\n }\n\n uint256 libraIdx = 0;\n for (uint256 i = logN + 1; i <= logN + 4; i++) {\n shplonkNuChallengeElements[i] = Fr.unwrap(proof.libraPolyEvals[libraIdx]);\n libraIdx++;\n }\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements)));\n (shplonkNu,) = splitChallenge(nextPreviousChallenge);\n }\n\n function generateShplonkZChallenge(Honk.ZKProof memory proof, Fr prevChallenge)\n internal\n pure\n returns (Fr shplonkZ, Fr nextPreviousChallenge)\n {\n uint256[3] memory shplonkZChallengeElements;\n shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge);\n\n shplonkZChallengeElements[1] = proof.shplonkQ.x;\n shplonkZChallengeElements[2] = proof.shplonkQ.y;\n\n nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements)));\n (shplonkZ,) = splitChallenge(nextPreviousChallenge);\n }\n\n function loadProof(bytes calldata proof, uint256 logN) internal pure returns (Honk.ZKProof memory p) {\n uint256 boundary = 0x0;\n\n // Pairing point object\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n // Commitments\n p.w1 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w2 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w3 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n // Lookup / Permutation Helper Commitments\n p.lookupReadCounts = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupReadTags = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.w4 = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.lookupInverses = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.zPerm = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[0] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n\n p.libraSum = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n // Sumcheck univariates\n for (uint256 i = 0; i < logN; i++) {\n for (uint256 j = 0; j < ZK_BATCHED_RELATION_PARTIAL_LENGTH; j++) {\n p.sumcheckUnivariates[i][j] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n }\n\n // Sumcheck evaluations\n for (uint256 i = 0; i < NUMBER_OF_ENTITIES; i++) {\n p.sumcheckEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n p.libraEvaluation = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n p.libraCommitments[1] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.libraCommitments[2] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingPoly = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n p.geminiMaskingEval = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n\n // Gemini\n // Read gemini fold univariates\n for (uint256 i = 0; i < logN - 1; i++) {\n p.geminiFoldComms[i] = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n }\n\n // Read gemini a evaluations\n for (uint256 i = 0; i < logN; i++) {\n p.geminiAEvaluations[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n for (uint256 i = 0; i < 4; i++) {\n p.libraPolyEvals[i] = bytesToFr(proof[boundary:boundary + FIELD_ELEMENT_SIZE]);\n boundary += FIELD_ELEMENT_SIZE;\n }\n\n // Shplonk\n p.shplonkQ = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n boundary += GROUP_ELEMENT_SIZE;\n // KZG\n p.kzgQuotient = bytesToG1Point(proof[boundary:boundary + GROUP_ELEMENT_SIZE]);\n }\n}\n\n// Field arithmetic libraries\n\nlibrary RelationsLib {\n Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)\n\n function accumulateRelationEvaluations(\n Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_ALPHAS] memory alphas,\n Fr powPartialEval\n ) internal pure returns (Fr accumulator) {\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations;\n\n // Accumulate all relations in Ultra Honk - each with varying number of subrelations\n accumulateArithmeticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePermutationRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateLogDerivativeLookupRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateDeltaRangeRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateEllipticRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulateMemoryRelation(purportedEvaluations, rp, evaluations, powPartialEval);\n accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);\n accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);\n\n // batch the subrelations with the alpha challenges to obtain the full honk relation\n accumulator = scaleAndBatchSubrelations(evaluations, alphas);\n }\n\n /**\n * Aesthetic helper function that is used to index by enum into proof.sumcheckEvaluations, it avoids\n * the relation checking code being cluttered with uint256 type casting, which is often a different colour in code\n * editors, and thus is noisy.\n */\n function wire(Fr[NUMBER_OF_ENTITIES] memory p, WIRE _wire) internal pure returns (Fr) {\n return p[uint256(_wire)];\n }\n\n uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;\n /**\n * Ultra Arithmetic Relation\n *\n */\n\n function accumulateArithmeticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n // Relation 0\n Fr q_arith = wire(p, WIRE.Q_ARITH);\n {\n Fr neg_half = Fr.wrap(NEG_HALF_MODULO_P);\n\n Fr accum = (q_arith - Fr.wrap(3)) * (wire(p, WIRE.Q_M) * wire(p, WIRE.W_R) * wire(p, WIRE.W_L)) * neg_half;\n accum = accum + (wire(p, WIRE.Q_L) * wire(p, WIRE.W_L)) + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_R))\n + (wire(p, WIRE.Q_O) * wire(p, WIRE.W_O)) + (wire(p, WIRE.Q_4) * wire(p, WIRE.W_4)) + wire(p, WIRE.Q_C);\n accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[0] = accum;\n }\n\n // Relation 1\n {\n Fr accum = wire(p, WIRE.W_L) + wire(p, WIRE.W_4) - wire(p, WIRE.W_L_SHIFT) + wire(p, WIRE.Q_M);\n accum = accum * (q_arith - Fr.wrap(2));\n accum = accum * (q_arith - ONE);\n accum = accum * q_arith;\n accum = accum * domainSep;\n evals[1] = accum;\n }\n }\n\n function accumulatePermutationRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr grand_product_numerator;\n Fr grand_product_denominator;\n\n {\n Fr num = wire(p, WIRE.W_L) + wire(p, WIRE.ID_1) * rp.beta + rp.gamma;\n num = num * (wire(p, WIRE.W_R) + wire(p, WIRE.ID_2) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_O) + wire(p, WIRE.ID_3) * rp.beta + rp.gamma);\n num = num * (wire(p, WIRE.W_4) + wire(p, WIRE.ID_4) * rp.beta + rp.gamma);\n\n grand_product_numerator = num;\n }\n {\n Fr den = wire(p, WIRE.W_L) + wire(p, WIRE.SIGMA_1) * rp.beta + rp.gamma;\n den = den * (wire(p, WIRE.W_R) + wire(p, WIRE.SIGMA_2) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_O) + wire(p, WIRE.SIGMA_3) * rp.beta + rp.gamma);\n den = den * (wire(p, WIRE.W_4) + wire(p, WIRE.SIGMA_4) * rp.beta + rp.gamma);\n\n grand_product_denominator = den;\n }\n\n // Contribution 2\n {\n Fr acc = (wire(p, WIRE.Z_PERM) + wire(p, WIRE.LAGRANGE_FIRST)) * grand_product_numerator;\n\n acc = acc\n - (\n (wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))\n * grand_product_denominator\n );\n acc = acc * domainSep;\n evals[2] = acc;\n }\n\n // Contribution 3\n {\n Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;\n evals[3] = acc;\n }\n }\n\n function accumulateLogDerivativeLookupRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr write_term;\n Fr read_term;\n\n // Calculate the write term (the table accumulation)\n {\n write_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.eta)\n + (wire(p, WIRE.TABLE_3) * rp.etaTwo) + (wire(p, WIRE.TABLE_4) * rp.etaThree);\n }\n\n // Calculate the write term\n {\n Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));\n Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);\n Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);\n\n read_term = derived_entry_1 + (derived_entry_2 * rp.eta) + (derived_entry_3 * rp.etaTwo)\n + (wire(p, WIRE.Q_O) * rp.etaThree);\n }\n\n Fr read_inverse = wire(p, WIRE.LOOKUP_INVERSES) * write_term;\n Fr write_inverse = wire(p, WIRE.LOOKUP_INVERSES) * read_term;\n\n Fr inverse_exists_xor = wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)\n - (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));\n\n // Inverse calculated correctly relation\n Fr accumulatorNone = read_term * write_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;\n accumulatorNone = accumulatorNone * domainSep;\n\n // Inverse\n Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * read_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * write_inverse;\n\n Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);\n\n Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;\n\n evals[4] = accumulatorNone;\n evals[5] = accumulatorOne;\n evals[6] = read_tag_boolean_relation * domainSep;\n }\n\n function accumulateDeltaRangeRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n Fr minus_one = ZERO - ONE;\n Fr minus_two = ZERO - Fr.wrap(2);\n Fr minus_three = ZERO - Fr.wrap(3);\n\n // Compute wire differences\n Fr delta_1 = wire(p, WIRE.W_R) - wire(p, WIRE.W_L);\n Fr delta_2 = wire(p, WIRE.W_O) - wire(p, WIRE.W_R);\n Fr delta_3 = wire(p, WIRE.W_4) - wire(p, WIRE.W_O);\n Fr delta_4 = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_4);\n\n // Contribution 6\n {\n Fr acc = delta_1;\n acc = acc * (delta_1 + minus_one);\n acc = acc * (delta_1 + minus_two);\n acc = acc * (delta_1 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[7] = acc;\n }\n\n // Contribution 7\n {\n Fr acc = delta_2;\n acc = acc * (delta_2 + minus_one);\n acc = acc * (delta_2 + minus_two);\n acc = acc * (delta_2 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[8] = acc;\n }\n\n // Contribution 8\n {\n Fr acc = delta_3;\n acc = acc * (delta_3 + minus_one);\n acc = acc * (delta_3 + minus_two);\n acc = acc * (delta_3 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[9] = acc;\n }\n\n // Contribution 9\n {\n Fr acc = delta_4;\n acc = acc * (delta_4 + minus_one);\n acc = acc * (delta_4 + minus_two);\n acc = acc * (delta_4 + minus_three);\n acc = acc * wire(p, WIRE.Q_RANGE);\n acc = acc * domainSep;\n evals[10] = acc;\n }\n }\n\n struct EllipticParams {\n // Points\n Fr x_1;\n Fr y_1;\n Fr x_2;\n Fr y_2;\n Fr y_3;\n Fr x_3;\n // push accumulators into memory\n Fr x_double_identity;\n }\n\n function accumulateEllipticRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n EllipticParams memory ep;\n ep.x_1 = wire(p, WIRE.W_R);\n ep.y_1 = wire(p, WIRE.W_O);\n\n ep.x_2 = wire(p, WIRE.W_L_SHIFT);\n ep.y_2 = wire(p, WIRE.W_4_SHIFT);\n ep.y_3 = wire(p, WIRE.W_O_SHIFT);\n ep.x_3 = wire(p, WIRE.W_R_SHIFT);\n\n Fr q_sign = wire(p, WIRE.Q_L);\n Fr q_is_double = wire(p, WIRE.Q_M);\n\n // Contribution 10 point addition, x-coordinate check\n // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0\n Fr x_diff = (ep.x_2 - ep.x_1);\n Fr y1_sqr = (ep.y_1 * ep.y_1);\n {\n // Move to top\n Fr partialEval = domainSep;\n\n Fr y2_sqr = (ep.y_2 * ep.y_2);\n Fr y1y2 = ep.y_1 * ep.y_2 * q_sign;\n Fr x_add_identity = (ep.x_3 + ep.x_2 + ep.x_1);\n x_add_identity = x_add_identity * x_diff * x_diff;\n x_add_identity = x_add_identity - y2_sqr - y1_sqr + y1y2 + y1y2;\n\n evals[11] = x_add_identity * partialEval * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 11 point addition, x-coordinate check\n // q_elliptic * (q_sign * y1 + y3)(x2 - x1) + (x3 - x1)(y2 - q_sign * y1) = 0\n {\n Fr y1_plus_y3 = ep.y_1 + ep.y_3;\n Fr y_diff = ep.y_2 * q_sign - ep.y_1;\n Fr y_add_identity = y1_plus_y3 * x_diff + (ep.x_3 - ep.x_1) * y_diff;\n evals[12] = y_add_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * (ONE - q_is_double);\n }\n\n // Contribution 10 point doubling, x-coordinate check\n // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0\n // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1\n {\n Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1;\n Fr y1_sqr_mul_4 = y1_sqr + y1_sqr;\n y1_sqr_mul_4 = y1_sqr_mul_4 + y1_sqr_mul_4;\n Fr x1_pow_4_mul_9 = x_pow_4 * Fr.wrap(9);\n\n // NOTE: pushed into memory (stack >:'( )\n ep.x_double_identity = (ep.x_3 + ep.x_1 + ep.x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;\n\n Fr acc = ep.x_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n evals[11] = evals[11] + acc;\n }\n\n // Contribution 11 point doubling, y-coordinate check\n // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0\n {\n Fr x1_sqr_mul_3 = (ep.x_1 + ep.x_1 + ep.x_1) * ep.x_1;\n Fr y_double_identity = x1_sqr_mul_3 * (ep.x_1 - ep.x_3) - (ep.y_1 + ep.y_1) * (ep.y_1 + ep.y_3);\n evals[12] = evals[12] + y_double_identity * domainSep * wire(p, WIRE.Q_ELLIPTIC) * q_is_double;\n }\n }\n\n // Parameters used within the Memory Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct MemParams {\n Fr memory_record_check;\n Fr partial_record_check;\n Fr next_gate_access_type;\n Fr record_delta;\n Fr index_delta;\n Fr adjacent_values_match_if_adjacent_indices_match;\n Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;\n Fr access_check;\n Fr next_gate_access_type_is_boolean;\n Fr ROM_consistency_check_identity;\n Fr RAM_consistency_check_identity;\n Fr timestamp_delta;\n Fr RAM_timestamp_check_identity;\n Fr memory_identity;\n Fr index_is_monotonically_increasing;\n }\n\n function accumulateMemoryRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Honk.RelationParameters memory rp,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n MemParams memory ap;\n\n /**\n * MEMORY\n *\n * A RAM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * t: `timestamp` of memory cell being accessed (used for RAM, set to 0 for ROM)\n * * v: `value` of memory cell being accessed\n * * a: `access` type of record. read: 0 = read, 1 = write\n * * r: `record` of memory cell. record = access + index * eta + timestamp * eta_two + value * eta_three\n *\n * A ROM memory record contains a tuple of the following fields:\n * * i: `index` of memory cell being accessed\n * * v: `value1` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * v2:`value2` of memory cell being accessed (ROM tables can store up to 2 values per index)\n * * r: `record` of memory cell. record = index * eta + value2 * eta_two + value1 * eta_three\n *\n * When performing a read/write access, the values of i, t, v, v2, a, r are stored in the following wires +\n * selectors, depending on whether the gate is a RAM read/write or a ROM read\n *\n * | gate type | i | v2/t | v | a | r |\n * | --------- | -- | ----- | -- | -- | -- |\n * | ROM | w1 | w2 | w3 | -- | w4 |\n * | RAM | w1 | w2 | w3 | qc | w4 |\n *\n * (for accesses where `index` is a circuit constant, it is assumed the circuit will apply a copy constraint on\n * `w2` to fix its value)\n *\n *\n */\n\n /**\n * Memory Record Check\n * Partial degree: 1\n * Total degree: 4\n *\n * A ROM/ROM access gate can be evaluated with the identity:\n *\n * qc + w1 \\eta + w2 \\eta_two + w3 \\eta_three - w4 = 0\n *\n * For ROM gates, qc = 0\n */\n ap.memory_record_check = wire(p, WIRE.W_O) * rp.etaThree;\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * rp.etaTwo);\n ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);\n ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);\n ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4\n ap.memory_record_check = ap.memory_record_check - wire(p, WIRE.W_4);\n\n /**\n * Contribution 13 & 14\n * ROM Consistency Check\n * Partial degree: 1\n * Total degree: 4\n *\n * For every ROM read, a set equivalence check is applied between the record witnesses, and a second set of\n * records that are sorted.\n *\n * We apply the following checks for the sorted records:\n *\n * 1. w1, w2, w3 correctly map to 'index', 'v1, 'v2' for a given record value at w4\n * 2. index values for adjacent records are monotonically increasing\n * 3. if, at gate i, index_i == index_{i + 1}, then value1_i == value1_{i + 1} and value2_i == value2_{i + 1}\n *\n */\n ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);\n ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);\n\n ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2\n\n ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2\n\n evals[14] = ap.adjacent_values_match_if_adjacent_indices_match * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n evals[15] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R))\n * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5\n\n ap.ROM_consistency_check_identity = ap.memory_record_check * (wire(p, WIRE.Q_L) * wire(p, WIRE.Q_R)); // deg 3 or 7\n\n /**\n * Contributions 15,16,17\n * RAM Consistency Check\n *\n * The 'access' type of the record is extracted with the expression `w_4 - ap.partial_record_check`\n * (i.e. for an honest Prover `w1 * eta + w2 * eta^2 + w3 * eta^3 - w4 = access`.\n * This is validated by requiring `access` to be boolean\n *\n * For two adjacent entries in the sorted list if _both_\n * A) index values match\n * B) adjacent access value is 0 (i.e. next gate is a READ)\n * then\n * C) both values must match.\n * The gate boolean check is\n * (A && B) => C === !(A && B) || C === !A || !B || C\n *\n * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized\n * with a WRITE operation.\n */\n Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4\n ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8\n\n // reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta\n // deg 1 or 4\n ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * rp.etaThree;\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * rp.etaTwo);\n ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);\n ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;\n\n Fr value_delta = wire(p, WIRE.W_O_SHIFT) - wire(p, WIRE.W_O);\n ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =\n (ap.index_delta * MINUS_ONE + ONE) * value_delta * (ap.next_gate_access_type * MINUS_ONE + ONE); // deg 3 or 6\n\n // We can't apply the RAM consistency check identity on the final entry in the sorted list (the wires in the\n // next gate would make the identity fail). We need to validate that its 'access type' bool is correct. Can't\n // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access\n // type is correct, to cover this edge case\n // deg 2 or 4\n ap.next_gate_access_type_is_boolean =\n ap.next_gate_access_type * ap.next_gate_access_type - ap.next_gate_access_type;\n\n // Putting it all together...\n evals[16] = ap.adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation\n * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 5 or 8\n evals[17] = ap.index_is_monotonically_increasing * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4\n evals[18] = ap.next_gate_access_type_is_boolean * (wire(p, WIRE.Q_O)) * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 6\n\n ap.RAM_consistency_check_identity = ap.access_check * (wire(p, WIRE.Q_O)); // deg 3 or 9\n\n /**\n * RAM Timestamp Consistency Check\n *\n * | w1 | w2 | w3 | w4 |\n * | index | timestamp | timestamp_check | -- |\n *\n * Let delta_index = index_{i + 1} - index_{i}\n *\n * Iff delta_index == 0, timestamp_check = timestamp_{i + 1} - timestamp_i\n * Else timestamp_check = 0\n */\n ap.timestamp_delta = wire(p, WIRE.W_R_SHIFT) - wire(p, WIRE.W_R);\n ap.RAM_timestamp_check_identity = (ap.index_delta * MINUS_ONE + ONE) * ap.timestamp_delta - wire(p, WIRE.W_O); // deg 3\n\n /**\n * Complete Contribution 12\n * The complete RAM/ROM memory identity\n * Partial degree:\n */\n ap.memory_identity = ap.ROM_consistency_check_identity; // deg 3 or 6\n ap.memory_identity =\n ap.memory_identity + ap.RAM_timestamp_check_identity * (wire(p, WIRE.Q_4) * wire(p, WIRE.Q_L)); // deg 4\n ap.memory_identity = ap.memory_identity + ap.memory_record_check * (wire(p, WIRE.Q_M) * wire(p, WIRE.Q_L)); // deg 3 or 6\n ap.memory_identity = ap.memory_identity + ap.RAM_consistency_check_identity; // deg 3 or 9\n\n // (deg 3 or 9) + (deg 4) + (deg 3)\n ap.memory_identity = ap.memory_identity * (wire(p, WIRE.Q_MEMORY) * domainSep); // deg 4 or 10\n evals[13] = ap.memory_identity;\n }\n\n // Constants for the Non-native Field relation\n Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);\n Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);\n\n // Parameters used within the Non-Native Field Relation\n // A struct is used to work around stack too deep. This relation has alot of variables\n struct NnfParams {\n Fr limb_subproduct;\n Fr non_native_field_gate_1;\n Fr non_native_field_gate_2;\n Fr non_native_field_gate_3;\n Fr limb_accumulator_1;\n Fr limb_accumulator_2;\n Fr nnf_identity;\n }\n\n function accumulateNnfRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n NnfParams memory ap;\n\n /**\n * Contribution 12\n * Non native field arithmetic gate 2\n * deg 4\n *\n * _ _\n * / _ _ _ 14 \\\n * q_2 . q_4 | (w_1 . w_2) + (w_1 . w_2) + (w_1 . w_4 + w_2 . w_3 - w_3) . 2 - w_3 - w_4 |\n * \\_ _/\n *\n *\n */\n ap.limb_subproduct = wire(p, WIRE.W_L) * wire(p, WIRE.W_R_SHIFT) + wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R);\n ap.non_native_field_gate_2 =\n (wire(p, WIRE.W_L) * wire(p, WIRE.W_4) + wire(p, WIRE.W_R) * wire(p, WIRE.W_O) - wire(p, WIRE.W_O_SHIFT));\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * LIMB_SIZE;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 - wire(p, WIRE.W_4_SHIFT);\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 + ap.limb_subproduct;\n ap.non_native_field_gate_2 = ap.non_native_field_gate_2 * wire(p, WIRE.Q_4);\n\n ap.limb_subproduct = ap.limb_subproduct * LIMB_SIZE;\n ap.limb_subproduct = ap.limb_subproduct + (wire(p, WIRE.W_L_SHIFT) * wire(p, WIRE.W_R_SHIFT));\n ap.non_native_field_gate_1 = ap.limb_subproduct;\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 - (wire(p, WIRE.W_O) + wire(p, WIRE.W_4));\n ap.non_native_field_gate_1 = ap.non_native_field_gate_1 * wire(p, WIRE.Q_O);\n\n ap.non_native_field_gate_3 = ap.limb_subproduct;\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 + wire(p, WIRE.W_4);\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 - (wire(p, WIRE.W_O_SHIFT) + wire(p, WIRE.W_4_SHIFT));\n ap.non_native_field_gate_3 = ap.non_native_field_gate_3 * wire(p, WIRE.Q_M);\n\n Fr non_native_field_identity =\n ap.non_native_field_gate_1 + ap.non_native_field_gate_2 + ap.non_native_field_gate_3;\n non_native_field_identity = non_native_field_identity * wire(p, WIRE.Q_R);\n\n // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm\n // deg 2\n ap.limb_accumulator_1 = wire(p, WIRE.W_R_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_O);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_R);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * SUBLIMB_SHIFT;\n ap.limb_accumulator_1 = ap.limb_accumulator_1 + wire(p, WIRE.W_L);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 - wire(p, WIRE.W_4);\n ap.limb_accumulator_1 = ap.limb_accumulator_1 * wire(p, WIRE.Q_4);\n\n // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * qm\n // deg 2\n ap.limb_accumulator_2 = wire(p, WIRE.W_O_SHIFT) * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_R_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_L_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_4);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * SUBLIMB_SHIFT;\n ap.limb_accumulator_2 = ap.limb_accumulator_2 + wire(p, WIRE.W_O);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 - wire(p, WIRE.W_4_SHIFT);\n ap.limb_accumulator_2 = ap.limb_accumulator_2 * wire(p, WIRE.Q_M);\n\n Fr limb_accumulator_identity = ap.limb_accumulator_1 + ap.limb_accumulator_2;\n limb_accumulator_identity = limb_accumulator_identity * wire(p, WIRE.Q_O); // deg 3\n\n ap.nnf_identity = non_native_field_identity + limb_accumulator_identity;\n ap.nnf_identity = ap.nnf_identity * (wire(p, WIRE.Q_NNF) * domainSep);\n evals[19] = ap.nnf_identity;\n }\n\n struct PoseidonExternalParams {\n Fr s1;\n Fr s2;\n Fr s3;\n Fr s4;\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr t0;\n Fr t1;\n Fr t2;\n Fr t3;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonExternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonExternalParams memory ep;\n\n ep.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n ep.s2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_R);\n ep.s3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_O);\n ep.s4 = wire(p, WIRE.W_4) + wire(p, WIRE.Q_4);\n\n ep.u1 = ep.s1 * ep.s1 * ep.s1 * ep.s1 * ep.s1;\n ep.u2 = ep.s2 * ep.s2 * ep.s2 * ep.s2 * ep.s2;\n ep.u3 = ep.s3 * ep.s3 * ep.s3 * ep.s3 * ep.s3;\n ep.u4 = ep.s4 * ep.s4 * ep.s4 * ep.s4 * ep.s4;\n // matrix mul v = M_E * u with 14 additions\n ep.t0 = ep.u1 + ep.u2; // u_1 + u_2\n ep.t1 = ep.u3 + ep.u4; // u_3 + u_4\n ep.t2 = ep.u2 + ep.u2 + ep.t1; // 2u_2\n // ep.t2 += ep.t1; // 2u_2 + u_3 + u_4\n ep.t3 = ep.u4 + ep.u4 + ep.t0; // 2u_4\n // ep.t3 += ep.t0; // u_1 + u_2 + 2u_4\n ep.v4 = ep.t1 + ep.t1;\n ep.v4 = ep.v4 + ep.v4 + ep.t3;\n // ep.v4 += ep.t3; // u_1 + u_2 + 4u_3 + 6u_4\n ep.v2 = ep.t0 + ep.t0;\n ep.v2 = ep.v2 + ep.v2 + ep.t2;\n // ep.v2 += ep.t2; // 4u_1 + 6u_2 + u_3 + u_4\n ep.v1 = ep.t3 + ep.v2; // 5u_1 + 7u_2 + u_3 + 3u_4\n ep.v3 = ep.t2 + ep.v4; // u_1 + 3u_2 + 5u_3 + 7u_4\n\n ep.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_EXTERNAL) * domainSep;\n evals[20] = evals[20] + ep.q_pos_by_scaling * (ep.v1 - wire(p, WIRE.W_L_SHIFT));\n\n evals[21] = evals[21] + ep.q_pos_by_scaling * (ep.v2 - wire(p, WIRE.W_R_SHIFT));\n\n evals[22] = evals[22] + ep.q_pos_by_scaling * (ep.v3 - wire(p, WIRE.W_O_SHIFT));\n\n evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n struct PoseidonInternalParams {\n Fr u1;\n Fr u2;\n Fr u3;\n Fr u4;\n Fr u_sum;\n Fr v1;\n Fr v2;\n Fr v3;\n Fr v4;\n Fr s1;\n Fr q_pos_by_scaling;\n }\n\n function accumulatePoseidonInternalRelation(\n Fr[NUMBER_OF_ENTITIES] memory p,\n Fr[NUMBER_OF_SUBRELATIONS] memory evals,\n Fr domainSep\n ) internal pure {\n PoseidonInternalParams memory ip;\n\n Fr[4] memory INTERNAL_MATRIX_DIAGONAL = [\n FrLib.from(0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7),\n FrLib.from(0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b),\n FrLib.from(0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15),\n FrLib.from(0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b)\n ];\n\n // add round constants\n ip.s1 = wire(p, WIRE.W_L) + wire(p, WIRE.Q_L);\n\n // apply s-box round\n ip.u1 = ip.s1 * ip.s1 * ip.s1 * ip.s1 * ip.s1;\n ip.u2 = wire(p, WIRE.W_R);\n ip.u3 = wire(p, WIRE.W_O);\n ip.u4 = wire(p, WIRE.W_4);\n\n // matrix mul with v = M_I * u 4 muls and 7 additions\n ip.u_sum = ip.u1 + ip.u2 + ip.u3 + ip.u4;\n\n ip.q_pos_by_scaling = wire(p, WIRE.Q_POSEIDON2_INTERNAL) * domainSep;\n\n ip.v1 = ip.u1 * INTERNAL_MATRIX_DIAGONAL[0] + ip.u_sum;\n evals[24] = evals[24] + ip.q_pos_by_scaling * (ip.v1 - wire(p, WIRE.W_L_SHIFT));\n\n ip.v2 = ip.u2 * INTERNAL_MATRIX_DIAGONAL[1] + ip.u_sum;\n evals[25] = evals[25] + ip.q_pos_by_scaling * (ip.v2 - wire(p, WIRE.W_R_SHIFT));\n\n ip.v3 = ip.u3 * INTERNAL_MATRIX_DIAGONAL[2] + ip.u_sum;\n evals[26] = evals[26] + ip.q_pos_by_scaling * (ip.v3 - wire(p, WIRE.W_O_SHIFT));\n\n ip.v4 = ip.u4 * INTERNAL_MATRIX_DIAGONAL[3] + ip.u_sum;\n evals[27] = evals[27] + ip.q_pos_by_scaling * (ip.v4 - wire(p, WIRE.W_4_SHIFT));\n }\n\n function scaleAndBatchSubrelations(\n Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,\n Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges\n ) internal pure returns (Fr accumulator) {\n accumulator = evaluations[0];\n\n for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {\n accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];\n }\n }\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\nlibrary CommitmentSchemeLib {\n using FrLib for Fr;\n\n // Avoid stack too deep\n struct ShpleminiIntermediates {\n Fr unshiftedScalar;\n Fr shiftedScalar;\n Fr unshiftedScalarNeg;\n Fr shiftedScalarNeg;\n // Scalar to be multiplied by [1]₁\n Fr constantTermAccumulator;\n // Accumulator for powers of rho\n Fr batchingChallenge;\n // Linear combination of multilinear (sumcheck) evaluations and powers of rho\n Fr batchedEvaluation;\n Fr[4] denominators;\n Fr[4] batchingScalars;\n // 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr posInvertedDenominator;\n // 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated\n Fr negInvertedDenominator;\n // ν^{2i} * 1/(z - r^{2^i})\n Fr scalingFactorPos;\n // ν^{2i+1} * 1/(z + r^{2^i})\n Fr scalingFactorNeg;\n // Fold_i(r^{2^i}) reconstructed by Verifier\n Fr[] foldPosEvaluations;\n }\n\n function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {\n Fr[] memory squares = new Fr[](logN);\n squares[0] = r;\n for (uint256 i = 1; i < logN; ++i) {\n squares[i] = squares[i - 1].sqr();\n }\n return squares;\n }\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1\n\n function computeFoldPosEvaluations(\n Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,\n Fr batchedEvalAccumulator,\n Fr[CONST_PROOF_SIZE_LOG_N] memory geminiEvaluations,\n Fr[] memory geminiEvalChallengePowers,\n uint256 logSize\n ) internal view returns (Fr[] memory) {\n Fr[] memory foldPosEvaluations = new Fr[](logSize);\n for (uint256 i = logSize; i > 0; --i) {\n Fr challengePower = geminiEvalChallengePowers[i - 1];\n Fr u = sumcheckUChallenges[i - 1];\n\n Fr batchedEvalRoundAcc = (\n (challengePower * batchedEvalAccumulator * Fr.wrap(2))\n - geminiEvaluations[i - 1] * (challengePower * (ONE - u) - u)\n );\n // Divide by the denominator\n batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();\n\n batchedEvalAccumulator = batchedEvalRoundAcc;\n foldPosEvaluations[i - 1] = batchedEvalRoundAcc;\n }\n return foldPosEvaluations;\n }\n}\n\nuint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q\n\nfunction bytes32ToString(bytes32 value) pure returns (string memory result) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(66);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < 32; i++) {\n str[2 + i * 2] = alphabet[uint8(value[i] >> 4)];\n str[3 + i * 2] = alphabet[uint8(value[i] & 0x0f)];\n }\n result = string(str);\n}\n\n// Fr utility\n\nfunction bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {\n scalar = FrLib.fromBytes32(bytes32(proofSection));\n}\n\n// EC Point utilities\nfunction bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {\n point = Honk.G1Point({\n x: uint256(bytes32(proofSection[0x00:0x20])) % Q,\n y: uint256(bytes32(proofSection[0x20:0x40])) % Q\n });\n}\n\nfunction negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {\n point.y = (Q - point.y) % Q;\n return point;\n}\n\n/**\n * Convert the pairing points to G1 points.\n *\n * The pairing points are serialised as an array of 68 bit limbs representing two points\n * The lhs of a pairing operation and the rhs of a pairing operation\n *\n * There are 4 fields for each group element, leaving 8 fields for each side of the pairing.\n *\n * @param pairingPoints The pairing points to convert.\n * @return lhs\n * @return rhs\n */\nfunction convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)\n pure\n returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)\n{\n uint256 lhsX = Fr.unwrap(pairingPoints[0]);\n lhsX |= Fr.unwrap(pairingPoints[1]) << 68;\n lhsX |= Fr.unwrap(pairingPoints[2]) << 136;\n lhsX |= Fr.unwrap(pairingPoints[3]) << 204;\n lhs.x = lhsX;\n\n uint256 lhsY = Fr.unwrap(pairingPoints[4]);\n lhsY |= Fr.unwrap(pairingPoints[5]) << 68;\n lhsY |= Fr.unwrap(pairingPoints[6]) << 136;\n lhsY |= Fr.unwrap(pairingPoints[7]) << 204;\n lhs.y = lhsY;\n\n uint256 rhsX = Fr.unwrap(pairingPoints[8]);\n rhsX |= Fr.unwrap(pairingPoints[9]) << 68;\n rhsX |= Fr.unwrap(pairingPoints[10]) << 136;\n rhsX |= Fr.unwrap(pairingPoints[11]) << 204;\n rhs.x = rhsX;\n\n uint256 rhsY = Fr.unwrap(pairingPoints[12]);\n rhsY |= Fr.unwrap(pairingPoints[13]) << 68;\n rhsY |= Fr.unwrap(pairingPoints[14]) << 136;\n rhsY |= Fr.unwrap(pairingPoints[15]) << 204;\n rhs.y = rhsY;\n}\n\n/**\n * Hash the pairing inputs from the present verification context with those extracted from the public inputs.\n *\n * @param proofPairingPoints Pairing points from the proof - (public inputs).\n * @param accLhs Accumulator point for the left side - result of shplemini.\n * @param accRhs Accumulator point for the right side - result of shplemini.\n * @return recursionSeparator The recursion separator - generated from hashing the above.\n */\nfunction generateRecursionSeparator(\n Fr[PAIRING_POINTS_SIZE] memory proofPairingPoints,\n Honk.G1Point memory accLhs,\n Honk.G1Point memory accRhs\n) pure returns (Fr recursionSeparator) {\n // hash the proof aggregated X\n // hash the proof aggregated Y\n // hash the accum X\n // hash the accum Y\n\n (Honk.G1Point memory proofLhs, Honk.G1Point memory proofRhs) = convertPairingPointsToG1(proofPairingPoints);\n\n uint256[8] memory recursionSeparatorElements;\n\n // Proof points\n recursionSeparatorElements[0] = proofLhs.x;\n recursionSeparatorElements[1] = proofLhs.y;\n recursionSeparatorElements[2] = proofRhs.x;\n recursionSeparatorElements[3] = proofRhs.y;\n\n // Accumulator points\n recursionSeparatorElements[4] = accLhs.x;\n recursionSeparatorElements[5] = accLhs.y;\n recursionSeparatorElements[6] = accRhs.x;\n recursionSeparatorElements[7] = accRhs.y;\n\n recursionSeparator = FrLib.fromBytes32(keccak256(abi.encodePacked(recursionSeparatorElements)));\n}\n\n/**\n * G1 Mul with Separator\n * Using the ecAdd and ecMul precompiles\n *\n * @param basePoint The point to multiply.\n * @param other The other point to add.\n * @param recursionSeperator The separator to use for the multiplication.\n * @return `(recursionSeperator * basePoint) + other`.\n */\nfunction mulWithSeperator(Honk.G1Point memory basePoint, Honk.G1Point memory other, Fr recursionSeperator)\n view\n returns (Honk.G1Point memory)\n{\n Honk.G1Point memory result;\n\n result = ecMul(recursionSeperator, basePoint);\n result = ecAdd(result, other);\n\n return result;\n}\n\n/**\n * G1 Mul\n * Takes a Fr value and a G1 point and uses the ecMul precompile to return the result.\n *\n * @param value The value to multiply the point by.\n * @param point The point to multiply.\n * @return result The result of the multiplication.\n */\nfunction ecMul(Fr value, Honk.G1Point memory point) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write the point into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | point.x\n // free + 0x20| point.y\n mstore(free, mload(point))\n mstore(add(free, 0x20), mload(add(point, 0x20)))\n // Write the scalar into memory (one 32 byte word)\n // Memory layout:\n // Address | value\n // free + 0x40| value\n mstore(add(free, 0x40), value)\n\n // Call the ecMul precompile, it takes in the following\n // [point.x, point.y, scalar], and returns the result back into the free memory location.\n let success := staticcall(gas(), 0x07, free, 0x60, free, 0x40)\n if iszero(success) {\n revert(0, 0)\n }\n // Copy the result of the multiplication back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x60))\n }\n\n return result;\n}\n\n/**\n * G1 Add\n * Takes two G1 points and uses the ecAdd precompile to return the result.\n *\n * @param lhs The left hand side of the addition.\n * @param rhs The right hand side of the addition.\n * @return result The result of the addition.\n */\nfunction ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (Honk.G1Point memory) {\n Honk.G1Point memory result;\n\n assembly {\n let free := mload(0x40)\n // Write lhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free | lhs.x\n // free + 0x20| lhs.y\n mstore(free, mload(lhs))\n mstore(add(free, 0x20), mload(add(lhs, 0x20)))\n\n // Write rhs into memory (two 32 byte words)\n // Memory layout:\n // Address | value\n // free + 0x40| rhs.x\n // free + 0x60| rhs.y\n mstore(add(free, 0x40), mload(rhs))\n mstore(add(free, 0x60), mload(add(rhs, 0x20)))\n\n // Call the ecAdd precompile, it takes in the following\n // [lhs.x, lhs.y, rhs.x, rhs.y], and returns their addition back into the free memory location.\n let success := staticcall(gas(), 0x06, free, 0x80, free, 0x40)\n if iszero(success) { revert(0, 0) }\n\n // Copy the result of the addition back into the result memory location.\n // Memory layout:\n // Address | value\n // result | result.x\n // result + 0x20| result.y\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n\n mstore(0x40, add(free, 0x80))\n }\n\n return result;\n}\n\nfunction validateOnCurve(Honk.G1Point memory point) pure {\n uint256 x = point.x;\n uint256 y = point.y;\n\n bool success = false;\n assembly {\n let xx := mulmod(x, x, Q)\n success := eq(mulmod(y, y, Q), addmod(mulmod(x, xx, Q), 3, Q))\n }\n\n require(success, \"point is not on the curve\");\n}\n\nfunction pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {\n bytes memory input = abi.encodePacked(\n rhs.x,\n rhs.y,\n // Fixed G2 point\n uint256(0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2),\n uint256(0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed),\n uint256(0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b),\n uint256(0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa),\n lhs.x,\n lhs.y,\n // G2 point from VK\n uint256(0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1),\n uint256(0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0),\n uint256(0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4),\n uint256(0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55)\n );\n\n (bool success, bytes memory result) = address(0x08).staticcall(input);\n decodedResult = success && abi.decode(result, (bool));\n}\n\n// Field arithmetic libraries - prevent littering the code with modmul / addmul\n\n\n\n\nabstract contract BaseZKHonkVerifier is IVerifier {\n using FrLib for Fr;\n\n uint256 immutable $N;\n uint256 immutable $LOG_N;\n uint256 immutable $VK_HASH;\n uint256 immutable $NUM_PUBLIC_INPUTS;\n\n constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {\n $N = _N;\n $LOG_N = _logN;\n $VK_HASH = _vkHash;\n $NUM_PUBLIC_INPUTS = _numPublicInputs;\n }\n\n // Errors\n error ProofLengthWrong();\n error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);\n error PublicInputsLengthWrong();\n error SumcheckFailed();\n error ShpleminiFailed();\n error GeminiChallengeInSubgroup();\n error ConsistencyCheckFailed();\n\n // Constants for proof length calculation (matching UltraKeccakZKFlavor)\n uint256 constant NUM_WITNESS_ENTITIES = 8;\n uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points\n uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements\n uint256 constant NUM_LIBRA_EVALUATIONS = 4; // libra evaluations\n\n // Calculate proof size based on log_n (matching UltraKeccakZKFlavor formula)\n function calculateProofSize(uint256 logN) internal pure returns (uint256) {\n // Witness and Libra commitments\n uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments\n proofLength += NUM_ELEMENTS_COMM * 4; // Libra concat, grand sum, quotient comms + Gemini masking\n\n // Sumcheck\n proofLength += logN * ZK_BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates\n proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations\n\n // Libra and Gemini\n proofLength += NUM_ELEMENTS_FR * 3; // Libra sum, claimed eval, Gemini masking eval\n proofLength += logN * NUM_ELEMENTS_FR; // Gemini a evaluations\n proofLength += NUM_LIBRA_EVALUATIONS * NUM_ELEMENTS_FR; // libra evaluations\n\n // PCS commitments\n proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments\n proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments\n\n // Pairing points\n proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs\n\n return proofLength;\n }\n\n uint256 constant SHIFTED_COMMITMENTS_START = 30;\n\n function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);\n\n function verify(bytes calldata proof, bytes32[] calldata publicInputs)\n public\n view\n override\n returns (bool verified)\n {\n // Calculate expected proof size based on $LOG_N\n uint256 expectedProofSize = calculateProofSize($LOG_N);\n\n // Check the received proof is the expected size where each field element is 32 bytes\n if (proof.length != expectedProofSize * 32) {\n revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);\n }\n\n Honk.VerificationKey memory vk = loadVerificationKey();\n Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof, $LOG_N);\n\n if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {\n revert PublicInputsLengthWrong();\n }\n\n // Generate the fiat shamir challenges for the whole protocol\n ZKTranscript memory t =\n ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS, $LOG_N);\n\n // Derive public input delta\n t.relationParameters.publicInputsDelta = computePublicInputDelta(\n publicInputs,\n p.pairingPointObject,\n t.relationParameters.beta,\n t.relationParameters.gamma, /*pubInputsOffset=*/\n 1\n );\n\n // Sumcheck\n if (!verifySumcheck(p, t)) revert SumcheckFailed();\n\n if (!verifyShplemini(p, vk, t)) revert ShpleminiFailed();\n\n verified = true;\n }\n\n uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;\n\n function computePublicInputDelta(\n bytes32[] memory publicInputs,\n Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,\n Fr beta,\n Fr gamma,\n uint256 offset\n ) internal view returns (Fr publicInputDelta) {\n Fr numerator = Fr.wrap(1);\n Fr denominator = Fr.wrap(1);\n\n Fr numeratorAcc = gamma + (beta * FrLib.from(PERMUTATION_ARGUMENT_VALUE_SEPARATOR + offset));\n Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));\n\n {\n for (uint256 i = 0; i < $NUM_PUBLIC_INPUTS - PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = FrLib.fromBytes32(publicInputs[i]);\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n\n for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {\n Fr pubInput = pairingPointObject[i];\n\n numerator = numerator * (numeratorAcc + pubInput);\n denominator = denominator * (denominatorAcc + pubInput);\n\n numeratorAcc = numeratorAcc + beta;\n denominatorAcc = denominatorAcc - beta;\n }\n }\n\n // Fr delta = numerator / denominator; // TOOO: batch invert later?\n publicInputDelta = FrLib.div(numerator, denominator);\n }\n\n function verifySumcheck(Honk.ZKProof memory proof, ZKTranscript memory tp) internal view returns (bool verified) {\n Fr roundTargetSum = tp.libraChallenge * proof.libraSum; // default 0\n Fr powPartialEvaluation = Fr.wrap(1);\n\n // We perform sumcheck reductions over log n rounds ( the multivariate degree )\n for (uint256 round; round < $LOG_N; ++round) {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];\n Fr totalSum = roundUnivariate[0] + roundUnivariate[1];\n if (totalSum != roundTargetSum) revert SumcheckFailed();\n\n Fr roundChallenge = tp.sumCheckUChallenges[round];\n\n // Update the round target for the next rounf\n roundTargetSum = computeNextTargetSum(roundUnivariate, roundChallenge);\n powPartialEvaluation =\n powPartialEvaluation * (Fr.wrap(1) + roundChallenge * (tp.gateChallenges[round] - Fr.wrap(1)));\n }\n\n // Last round\n Fr grandHonkRelationSum = RelationsLib.accumulateRelationEvaluations(\n proof.sumcheckEvaluations, tp.relationParameters, tp.alphas, powPartialEvaluation\n );\n\n Fr evaluation = Fr.wrap(1);\n for (uint256 i = 2; i < $LOG_N; i++) {\n evaluation = evaluation * tp.sumCheckUChallenges[i];\n }\n\n grandHonkRelationSum =\n grandHonkRelationSum * (Fr.wrap(1) - evaluation) + proof.libraEvaluation * tp.libraChallenge;\n verified = (grandHonkRelationSum == roundTargetSum);\n }\n\n // Return the new target sum for the next sumcheck round\n function computeNextTargetSum(Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)\n internal\n view\n returns (Fr targetSum)\n {\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000000240),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31),\n Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000005a0),\n Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),\n Fr.wrap(0x0000000000000000000000000000000000000000000000000000000000009d80)\n ];\n\n // To compute the next target sum, we evaluate the given univariate at a point u (challenge).\n\n // Performing Barycentric evaluations\n // Compute B(x)\n Fr numeratorValue = Fr.wrap(1);\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i));\n }\n\n Fr[ZK_BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses;\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n denominatorInverses[i] = FrLib.invert(BARYCENTRIC_LAGRANGE_DENOMINATORS[i] * (roundChallenge - Fr.wrap(i)));\n }\n\n for (uint256 i = 0; i < ZK_BATCHED_RELATION_PARTIAL_LENGTH; ++i) {\n targetSum = targetSum + roundUnivariates[i] * denominatorInverses[i];\n }\n\n // Scale the sum by the value of B(x)\n targetSum = targetSum * numeratorValue;\n }\n\n uint256 constant LIBRA_COMMITMENTS = 3;\n uint256 constant LIBRA_EVALUATIONS = 4;\n uint256 constant LIBRA_UNIVARIATES_LENGTH = 9;\n\n struct PairingInputs {\n Honk.G1Point P_0;\n Honk.G1Point P_1;\n }\n\n function verifyShplemini(Honk.ZKProof memory proof, Honk.VerificationKey memory vk, ZKTranscript memory tp)\n internal\n view\n returns (bool verified)\n {\n CommitmentSchemeLib.ShpleminiIntermediates memory mem; // stack\n\n // - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size\n Fr[] memory powers_of_evaluation_challenge = CommitmentSchemeLib.computeSquares(tp.geminiR, $LOG_N);\n // Arrays hold values that will be linearly combined for the gemini and shplonk batch openings\n Fr[] memory scalars = new Fr[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n Honk.G1Point[] memory commitments = new Honk.G1Point[](NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3);\n\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[0]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[0]).invert();\n\n mem.unshiftedScalar = mem.posInvertedDenominator + (tp.shplonkNu * mem.negInvertedDenominator);\n mem.shiftedScalar =\n tp.geminiR.invert() * (mem.posInvertedDenominator - (tp.shplonkNu * mem.negInvertedDenominator));\n\n scalars[0] = Fr.wrap(1);\n commitments[0] = proof.shplonkQ;\n\n /* Batch multivariate opening claims, shifted and unshifted\n * The vector of scalars is populated as follows:\n * \\f[\n * \\left(\n * - \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{i+k-1} \\times \\left(\\frac{1}{z-r} + \\nu \\times \\frac{1}{z+r}\\right),\n * - \\rho^{i+k} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right),\n * \\ldots,\n * - \\rho^{k+m-1} \\times \\frac{1}{r} \\times \\left(\\frac{1}{z-r} - \\nu \\times \\frac{1}{z+r}\\right)\n * \\right)\n * \\f]\n *\n * The following vector is concatenated to the vector of commitments:\n * \\f[\n * f_0, \\ldots, f_{m-1}, f_{\\text{shift}, 0}, \\ldots, f_{\\text{shift}, k-1}\n * \\f]\n *\n * Simultaneously, the evaluation of the multilinear polynomial\n * \\f[\n * \\sum \\rho^i \\cdot f_i + \\sum \\rho^{i+k} \\cdot f_{\\text{shift}, i}\n * \\f]\n * at the challenge point \\f$ (u_0,\\ldots, u_{n-1}) \\f$ is computed.\n *\n * This approach minimizes the number of iterations over the commitments to multilinear polynomials\n * and eliminates the need to store the powers of \\f$ \\rho \\f$.\n */\n mem.batchedEvaluation = proof.geminiMaskingEval;\n mem.batchingChallenge = tp.rho;\n mem.unshiftedScalarNeg = mem.unshiftedScalar.neg();\n mem.shiftedScalarNeg = mem.shiftedScalar.neg();\n\n scalars[1] = mem.unshiftedScalarNeg;\n for (uint256 i = 0; i < NUMBER_UNSHIFTED; ++i) {\n scalars[i + 2] = mem.unshiftedScalarNeg * mem.batchingChallenge;\n mem.batchedEvaluation = mem.batchedEvaluation + (proof.sumcheckEvaluations[i] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n // g commitments are accumulated at r\n // For each of the to be shifted commitments perform the shift in place by\n // adding to the unshifted value.\n // We do so, as the values are to be used in batchMul later, and as\n // `a * c + b * c = (a + b) * c` this will allow us to reduce memory and compute.\n // Applied to w1, w2, w3, w4 and zPerm\n for (uint256 i = 0; i < NUMBER_TO_BE_SHIFTED; ++i) {\n uint256 scalarOff = i + SHIFTED_COMMITMENTS_START;\n uint256 evaluationOff = i + NUMBER_UNSHIFTED;\n\n scalars[scalarOff] = scalars[scalarOff] + (mem.shiftedScalarNeg * mem.batchingChallenge);\n mem.batchedEvaluation =\n mem.batchedEvaluation + (proof.sumcheckEvaluations[evaluationOff] * mem.batchingChallenge);\n mem.batchingChallenge = mem.batchingChallenge * tp.rho;\n }\n\n commitments[1] = proof.geminiMaskingPoly;\n\n commitments[2] = vk.qm;\n commitments[3] = vk.qc;\n commitments[4] = vk.ql;\n commitments[5] = vk.qr;\n commitments[6] = vk.qo;\n commitments[7] = vk.q4;\n commitments[8] = vk.qLookup;\n commitments[9] = vk.qArith;\n commitments[10] = vk.qDeltaRange;\n commitments[11] = vk.qElliptic;\n commitments[12] = vk.qMemory;\n commitments[13] = vk.qNnf;\n commitments[14] = vk.qPoseidon2External;\n commitments[15] = vk.qPoseidon2Internal;\n commitments[16] = vk.s1;\n commitments[17] = vk.s2;\n commitments[18] = vk.s3;\n commitments[19] = vk.s4;\n commitments[20] = vk.id1;\n commitments[21] = vk.id2;\n commitments[22] = vk.id3;\n commitments[23] = vk.id4;\n commitments[24] = vk.t1;\n commitments[25] = vk.t2;\n commitments[26] = vk.t3;\n commitments[27] = vk.t4;\n commitments[28] = vk.lagrangeFirst;\n commitments[29] = vk.lagrangeLast;\n\n // Accumulate proof points\n commitments[30] = proof.w1;\n commitments[31] = proof.w2;\n commitments[32] = proof.w3;\n commitments[33] = proof.w4;\n commitments[34] = proof.zPerm;\n commitments[35] = proof.lookupInverses;\n commitments[36] = proof.lookupReadCounts;\n commitments[37] = proof.lookupReadTags;\n\n /* Batch gemini claims from the prover\n * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from\n * aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars\n *\n * 1. Moves the vector\n * \\f[\n * \\left( \\text{com}(A_1), \\text{com}(A_2), \\ldots, \\text{com}(A_{n-1}) \\right)\n * \\f]\n * to the 'commitments' vector.\n *\n * 2. Computes the scalars:\n * \\f[\n * \\frac{\\nu^{2}}{z + r^2}, \\frac{\\nu^3}{z + r^4}, \\ldots, \\frac{\\nu^{n-1}}{z + r^{2^{n-1}}}\n * \\f]\n * and places them into the 'scalars' vector.\n *\n * 3. Accumulates the summands of the constant term:\n * \\f[\n * \\sum_{i=2}^{n-1} \\frac{\\nu^{i} \\cdot A_i(-r^{2^i})}{z + r^{2^i}}\n * \\f]\n * and adds them to the 'constant_term_accumulator'.\n */\n\n // Add contributions from A₀(r) and A₀(-r) to constant_term_accumulator:\n // Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., $LOG_N - 1\n Fr[] memory foldPosEvaluations = CommitmentSchemeLib.computeFoldPosEvaluations(\n tp.sumCheckUChallenges,\n mem.batchedEvaluation,\n proof.geminiAEvaluations,\n powers_of_evaluation_challenge,\n $LOG_N\n );\n\n mem.constantTermAccumulator = foldPosEvaluations[0] * mem.posInvertedDenominator;\n mem.constantTermAccumulator =\n mem.constantTermAccumulator + (proof.geminiAEvaluations[0] * tp.shplonkNu * mem.negInvertedDenominator);\n\n mem.batchingChallenge = tp.shplonkNu.sqr();\n uint256 boundary = NUMBER_UNSHIFTED + 2;\n\n // Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;\n // Compute scalar multipliers for each fold commitment\n for (uint256 i = 0; i < $LOG_N - 1; ++i) {\n bool dummy_round = i >= ($LOG_N - 1);\n\n if (!dummy_round) {\n // Update inverted denominators\n mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();\n mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();\n\n // Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]\n mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;\n mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;\n scalars[boundary + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();\n\n // Accumulate the const term contribution given by\n // v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})\n Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];\n accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];\n mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;\n }\n // Update the running power of v\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n\n commitments[boundary + i] = proof.geminiFoldComms[i];\n }\n\n boundary += $LOG_N - 1;\n\n // Finalize the batch opening claim\n mem.denominators[0] = Fr.wrap(1).div(tp.shplonkZ - tp.geminiR);\n mem.denominators[1] = Fr.wrap(1).div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);\n mem.denominators[2] = mem.denominators[0];\n mem.denominators[3] = mem.denominators[0];\n\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;\n for (uint256 i = 0; i < LIBRA_EVALUATIONS; i++) {\n Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;\n mem.batchingScalars[i] = scalingFactor.neg();\n mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;\n mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];\n }\n scalars[boundary] = mem.batchingScalars[0];\n scalars[boundary + 1] = mem.batchingScalars[1] + mem.batchingScalars[2];\n scalars[boundary + 2] = mem.batchingScalars[3];\n\n for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {\n commitments[boundary++] = proof.libraCommitments[i];\n }\n\n commitments[boundary] = Honk.G1Point({x: 1, y: 2});\n scalars[boundary++] = mem.constantTermAccumulator;\n\n if (!checkEvalsConsistency(proof.libraPolyEvals, tp.geminiR, tp.sumCheckUChallenges, proof.libraEvaluation)) {\n revert ConsistencyCheckFailed();\n }\n\n Honk.G1Point memory quotient_commitment = proof.kzgQuotient;\n\n commitments[boundary] = quotient_commitment;\n scalars[boundary] = tp.shplonkZ; // evaluation challenge\n\n PairingInputs memory pair;\n pair.P_0 = batchMul(commitments, scalars);\n pair.P_1 = negateInplace(quotient_commitment);\n\n // Aggregate pairing points\n Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, pair.P_0, pair.P_1);\n (Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =\n convertPairingPointsToG1(proof.pairingPointObject);\n\n // Validate the points from the proof are on the curve\n validateOnCurve(P_0_other);\n validateOnCurve(P_1_other);\n\n // accumulate with aggregate points in proof\n pair.P_0 = mulWithSeperator(pair.P_0, P_0_other, recursionSeparator);\n pair.P_1 = mulWithSeperator(pair.P_1, P_1_other, recursionSeparator);\n\n return pairing(pair.P_0, pair.P_1);\n }\n\n struct SmallSubgroupIpaIntermediates {\n Fr[SUBGROUP_SIZE] challengePolyLagrange;\n Fr challengePolyEval;\n Fr lagrangeFirst;\n Fr lagrangeLast;\n Fr rootPower;\n Fr[SUBGROUP_SIZE] denominators; // this has to disappear\n Fr diff;\n }\n\n function checkEvalsConsistency(\n Fr[LIBRA_EVALUATIONS] memory libraPolyEvals,\n Fr geminiR,\n Fr[CONST_PROOF_SIZE_LOG_N] memory uChallenges,\n Fr libraEval\n ) internal view returns (bool check) {\n Fr one = Fr.wrap(1);\n Fr vanishingPolyEval = geminiR.pow(SUBGROUP_SIZE) - one;\n if (vanishingPolyEval == Fr.wrap(0)) {\n revert GeminiChallengeInSubgroup();\n }\n\n SmallSubgroupIpaIntermediates memory mem;\n mem.challengePolyLagrange[0] = one;\n for (uint256 round = 0; round < $LOG_N; round++) {\n uint256 currIdx = 1 + LIBRA_UNIVARIATES_LENGTH * round;\n mem.challengePolyLagrange[currIdx] = one;\n for (uint256 idx = currIdx + 1; idx < currIdx + LIBRA_UNIVARIATES_LENGTH; idx++) {\n mem.challengePolyLagrange[idx] = mem.challengePolyLagrange[idx - 1] * uChallenges[round];\n }\n }\n\n mem.rootPower = one;\n mem.challengePolyEval = Fr.wrap(0);\n for (uint256 idx = 0; idx < SUBGROUP_SIZE; idx++) {\n mem.denominators[idx] = mem.rootPower * geminiR - one;\n mem.denominators[idx] = mem.denominators[idx].invert();\n mem.challengePolyEval = mem.challengePolyEval + mem.challengePolyLagrange[idx] * mem.denominators[idx];\n mem.rootPower = mem.rootPower * SUBGROUP_GENERATOR_INVERSE;\n }\n\n Fr numerator = vanishingPolyEval * Fr.wrap(SUBGROUP_SIZE).invert();\n mem.challengePolyEval = mem.challengePolyEval * numerator;\n mem.lagrangeFirst = mem.denominators[0] * numerator;\n mem.lagrangeLast = mem.denominators[SUBGROUP_SIZE - 1] * numerator;\n\n mem.diff = mem.lagrangeFirst * libraPolyEvals[2];\n\n mem.diff = mem.diff\n + (geminiR - SUBGROUP_GENERATOR_INVERSE)\n * (libraPolyEvals[1] - libraPolyEvals[2] - libraPolyEvals[0] * mem.challengePolyEval);\n mem.diff = mem.diff + mem.lagrangeLast * (libraPolyEvals[2] - libraEval) - vanishingPolyEval * libraPolyEvals[3];\n\n check = mem.diff == Fr.wrap(0);\n }\n\n // This implementation is the same as above with different constants\n function batchMul(Honk.G1Point[] memory base, Fr[] memory scalars)\n internal\n view\n returns (Honk.G1Point memory result)\n {\n uint256 limit = NUMBER_UNSHIFTED + $LOG_N + LIBRA_COMMITMENTS + 3;\n\n // Validate all points are on the curve\n for (uint256 i = 0; i < limit; ++i) {\n validateOnCurve(base[i]);\n }\n\n bool success = true;\n assembly {\n let free := mload(0x40)\n\n let count := 0x01\n for {} lt(count, add(limit, 1)) { count := add(count, 1) } {\n // Get loop offsets\n let base_base := add(base, mul(count, 0x20))\n let scalar_base := add(scalars, mul(count, 0x20))\n\n mstore(add(free, 0x40), mload(mload(base_base)))\n mstore(add(free, 0x60), mload(add(0x20, mload(base_base))))\n // Add scalar\n mstore(add(free, 0x80), mload(scalar_base))\n\n success := and(success, staticcall(gas(), 7, add(free, 0x40), 0x60, add(free, 0x40), 0x40))\n // accumulator = accumulator + accumulator_2\n success := and(success, staticcall(gas(), 6, free, 0x80, free, 0x40))\n }\n\n // Return the result\n mstore(result, mload(free))\n mstore(add(result, 0x20), mload(add(free, 0x20)))\n }\n\n require(success, ShpleminiFailed());\n }\n}\n\ncontract DepositVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {\n function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {\n return HonkVerificationKey.loadVerificationKey();\n }\n}\n" + } + } + } +} diff --git a/contracts/ignition/deployments/chain-421614/deployed_addresses.json b/contracts/ignition/deployments/chain-421614/deployed_addresses.json new file mode 100644 index 0000000..56ec8b5 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/deployed_addresses.json @@ -0,0 +1,14 @@ +{ + "tokens#AUDD": "0xA09599efa9a31036D20a9eEF07C69E77937E784E", + "tokens#FourDEC": "0xf90c7e5FbC840B381002279B555dc3e0290Da095", + "tokens#USDC": "0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51", + "depositVerifier#DepositVerifierLib": "0x9A0E3f3d11F7bA8B92faD4533043b5994615629d", + "transferExternalVerifier#TransferVerifierLib": "0xc246Abca0566848759dA29c30Fc77DC4A9962919", + "transferVerifier#TransferVerifierLib": "0x840feC4Efbd4764edAA237E78757cE59CeA3Db26", + "withdrawVerifier#WithdrawVerifierLib": "0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815", + "depositVerifier#DepositVerifier": "0xd3090af4727886D9b51FA38AC001025796Dd5E14", + "transferExternalVerifier#TransferExternalVerifier": "0x287243bD7650643B691cED24dfE854964Df045A1", + "transferVerifier#TransferVerifier": "0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e", + "withdrawVerifier#WithdrawVerifier": "0x8a6753C2fFb09Ab4d64763a8C5Ef4b31aF5f9Eb2", + "commbankDotEth#CommBankDotEth": "0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3" +} diff --git a/contracts/ignition/deployments/chain-421614/journal.jsonl b/contracts/ignition/deployments/chain-421614/journal.jsonl new file mode 100644 index 0000000..ec8f185 --- /dev/null +++ b/contracts/ignition/deployments/chain-421614/journal.jsonl @@ -0,0 +1,74 @@ + +{"chainId":421614,"type":"DEPLOYMENT_INITIALIZE"} +{"artifactId":"tokens#AUDD","constructorArgs":[],"contractName":"AUDD","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"tokens#AUDD","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"tokens#AUDD","networkInteraction":{"data":"0x608060405234801561000f575f5ffd5b506040805180820182526004808252631055511160e21b602080840182905284518086019095529184529083015290600361004a838261026e565b506004610057828261026e565b50505061006e33633b9aca0061007360201b60201c565b61034d565b6001600160a01b0382166100a15760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ac5f83836100b0565b5050565b6001600160a01b0383166100da578060025f8282546100cf9190610328565b9091555061014a9050565b6001600160a01b0383165f908152602081905260409020548181101561012c5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610098565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016657600280548290039055610184565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101c991815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806101fe57607f821691505b60208210810361021c57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026957805f5260205f20601f840160051c810160208510156102475750805b601f840160051c820191505b81811015610266575f8155600101610253565b50505b505050565b81516001600160401b03811115610287576102876101d6565b61029b8161029584546101ea565b84610222565b6020601f8211600181146102cd575f83156102b65750848201515b5f19600385901b1c1916600184901b178455610266565b5f84815260208120601f198516915b828110156102fc57878501518255602094850194600190920191016102dc565b508482101561031957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034757634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035a5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220ec03718ff94b552bfffd8fec13417b7e7ca5c7ae77ec71d1e8c9060cda1cd96e64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"tokens#AUDD","networkInteractionId":1,"nonce":1,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"tokens#AUDD","networkInteractionId":1,"nonce":1,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40048000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x14103c3d68489d2749422d9d137ce1d931aae65e2fc28f6bbcc18e154c979b76"},"type":"TRANSACTION_SEND"} +{"artifactId":"tokens#FourDEC","constructorArgs":[],"contractName":"FourDEC","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"tokens#FourDEC","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"tokens#FourDEC","networkInteraction":{"data":"0x608060405234801561000f575f5ffd5b50604080518082018252600780825266466f757244454360c81b602080840182905284518086019095529184529083015290600361004d8382610270565b50600461005a8282610270565b505050610070336298968061007560201b60201c565b61034f565b6001600160a01b0382166100a35760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ae5f83836100b2565b5050565b6001600160a01b0383166100dc578060025f8282546100d1919061032a565b9091555061014c9050565b6001600160a01b0383165f908152602081905260409020548181101561012e5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161009a565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016857600280548290039055610186565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101cb91815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061020057607f821691505b60208210810361021e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026b57805f5260205f20601f840160051c810160208510156102495750805b601f840160051c820191505b81811015610268575f8155600101610255565b50505b505050565b81516001600160401b03811115610289576102896101d8565b61029d8161029784546101ec565b84610224565b6020601f8211600181146102cf575f83156102b85750848201515b5f19600385901b1c1916600184901b178455610268565b5f84815260208120601f198516915b828110156102fe57878501518255602094850194600190920191016102de565b508482101561031b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034957634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035c5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600481526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea2646970667358221220de39d23dc8cf5d145e964ff008ad8dc2391d50090a52cd0410790e031fc99c2e64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"tokens#FourDEC","networkInteractionId":1,"nonce":2,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"tokens#FourDEC","networkInteractionId":1,"nonce":2,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40064000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xc744ced18ec440d5292053ffc3992b4498ba4a2d48609a951c005442d5270cb7"},"type":"TRANSACTION_SEND"} +{"artifactId":"tokens#USDC","constructorArgs":[],"contractName":"USDC","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"tokens#USDC","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"tokens#USDC","networkInteraction":{"data":"0x608060405234801561000f575f5ffd5b506040805180820182526004808252635553444360e01b602080840182905284518086019095529184529083015290600361004a838261026e565b506004610057828261026e565b50505061006e33633b9aca0061007360201b60201c565b61034d565b6001600160a01b0382166100a15760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ac5f83836100b0565b5050565b6001600160a01b0383166100da578060025f8282546100cf9190610328565b9091555061014a9050565b6001600160a01b0383165f908152602081905260409020548181101561012c5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610098565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661016657600280548290039055610184565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101c991815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806101fe57607f821691505b60208210810361021c57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561026957805f5260205f20601f840160051c810160208510156102475750805b601f840160051c820191505b81811015610266575f8155600101610253565b50505b505050565b81516001600160401b03811115610287576102876101d6565b61029b8161029584546101ea565b84610222565b6020601f8211600181146102cd575f83156102b65750848201515b5f19600385901b1c1916600184901b178455610266565b5f84815260208120601f198516915b828110156102fc57878501518255602094850194600190920191016102dc565b508482101561031957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561034757634e487b7160e01b5f52601160045260245ffd5b92915050565b6107468061035a5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461011457806370a082311461012957806395d89b4114610151578063a9059cbb14610159578063dd62ed3e1461016c575f5ffd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f2578063313ce56714610105575b5f5ffd5b6100a761017f565b6040516100b49190610581565b60405180910390f35b6100d06100cb3660046105d1565b61020f565b60405190151581526020016100b4565b6002545b6040519081526020016100b4565b6100d06101003660046105f9565b610228565b604051600681526020016100b4565b6101276101223660046105d1565b61024b565b005b6100e4610137366004610633565b6001600160a01b03165f9081526020819052604090205490565b6100a7610259565b6100d06101673660046105d1565b610268565b6100e461017a366004610653565b610275565b60606003805461018e90610684565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610684565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b5050505050905090565b5f3361021c81858561029f565b60019150505b92915050565b5f336102358582856102b1565b61024085858561030b565b506001949350505050565b6102558282610368565b5050565b60606004805461018e90610684565b5f3361021c81858561030b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6102ac838383600161039c565b505050565b5f6102bc8484610275565b90505f1981101561030557818110156102f757828183604051637dc7a0d960e11b81526004016102ee939291906106bc565b60405180910390fd5b61030584848484035f61039c565b50505050565b6001600160a01b038316610334575f604051634b637e8f60e11b81526004016102ee91906106dd565b6001600160a01b03821661035d575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102ac83838361046e565b6001600160a01b038216610391575f60405163ec442f0560e01b81526004016102ee91906106dd565b6102555f838361046e565b6001600160a01b0384166103c5575f60405163e602df0560e01b81526004016102ee91906106dd565b6001600160a01b0383166103ee575f604051634a1406b160e11b81526004016102ee91906106dd565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561030557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161046091815260200190565b60405180910390a350505050565b6001600160a01b038316610498578060025f82825461048d91906106f1565b909155506104f59050565b6001600160a01b0383165f90815260208190526040902054818110156104d75783818360405163391434e360e21b81526004016102ee939291906106bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166105115760028054829003905561052f565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161057491815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146105cc575f5ffd5b919050565b5f5f604083850312156105e2575f5ffd5b6105eb836105b6565b946020939093013593505050565b5f5f5f6060848603121561060b575f5ffd5b610614846105b6565b9250610622602085016105b6565b929592945050506040919091013590565b5f60208284031215610643575f5ffd5b61064c826105b6565b9392505050565b5f5f60408385031215610664575f5ffd5b61066d836105b6565b915061067b602084016105b6565b90509250929050565b600181811c9082168061069857607f821691505b6020821081036106b657634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0391909116815260200190565b8082018082111561022257634e487b7160e01b5f52601160045260245ffdfea26469706673582212201cfb0beb6ebddb40b7047788b0cede7eb1b4e67bb1b9174e2f81a21ba6a89c6364736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"tokens#USDC","networkInteractionId":1,"nonce":3,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"tokens#USDC","networkInteractionId":1,"nonce":3,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x790fba51a89a18a3284c5926625a6c3ea5ddf243bc8a6f6d678673a26cc9c578"},"type":"TRANSACTION_SEND"} +{"futureId":"tokens#AUDD","hash":"0x14103c3d68489d2749422d9d137ce1d931aae65e2fc28f6bbcc18e154c979b76","networkInteractionId":1,"receipt":{"blockHash":"0x9ad709eae72af23a62210ead5593c4534324f92e9f4c3781ee0c5b7f8a479d93","blockNumber":233653573,"contractAddress":"0xA09599efa9a31036D20a9eEF07C69E77937E784E","logs":[{"address":"0xA09599efa9a31036D20a9eEF07C69E77937E784E","data":"0x000000000000000000000000000000000000000000000000000000003b9aca00","logIndex":0,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"tokens#AUDD","result":{"address":"0xA09599efa9a31036D20a9eEF07C69E77937E784E","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"tokens#FourDEC","hash":"0xc744ced18ec440d5292053ffc3992b4498ba4a2d48609a951c005442d5270cb7","networkInteractionId":1,"receipt":{"blockHash":"0x5da7758729f411844f1e68d64e2eae79baa360130462e42146c065d382bf0808","blockNumber":233653583,"contractAddress":"0xf90c7e5FbC840B381002279B555dc3e0290Da095","logs":[{"address":"0xf90c7e5FbC840B381002279B555dc3e0290Da095","data":"0x0000000000000000000000000000000000000000000000000000000000989680","logIndex":0,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"tokens#FourDEC","result":{"address":"0xf90c7e5FbC840B381002279B555dc3e0290Da095","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"tokens#USDC","hash":"0x790fba51a89a18a3284c5926625a6c3ea5ddf243bc8a6f6d678673a26cc9c578","networkInteractionId":1,"receipt":{"blockHash":"0xfded9bf3c3f39c9886f33bb4ea0852c4144726807064509903d60c1b2bff6306","blockNumber":233653592,"contractAddress":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51","logs":[{"address":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51","data":"0x000000000000000000000000000000000000000000000000000000003b9aca00","logIndex":3,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"tokens#USDC","result":{"address":"0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"depositVerifier#DepositVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/DepositVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d2f7fadb24d448c1702d38d264f98318a75fe0f22f27a8576903a943b47cce0c64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":4,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","networkInteractionId":1,"nonce":4,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40032000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x68fd541e32966a4a4118ed562305e1dd7466f92750067ec81916351941c5452f"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferExternalVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea26469706673582212206aea036992d57cef20fa26361e4b6d125809a591183991e85495ab9935d44b3b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":5,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":5,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xb72c8b03a42f378aafbbb40ebd77f6ba946ae72008be88d88ac969530683aae0"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferVerifier#TransferVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/TransferVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220d70b529d6db1e39f40971ae88f4f01f8807ba4ebd127125bd7efbbd4cbecef2d64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":6,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifierLib","networkInteractionId":1,"nonce":6,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40176000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x10463c715c3cf17a2bd738c072745e0868a7f1af07c25f920529fc3c46eaf091"},"type":"TRANSACTION_SEND"} +{"artifactId":"withdrawVerifier#WithdrawVerifierLib","constructorArgs":[],"contractName":"contracts/verifiers/WithdrawVerifier.sol:ZKTranscriptLib","dependencies":[],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifierLib","futureType":"NAMED_ARTIFACT_LIBRARY_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteraction":{"data":"0x611732610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610034575f3560e01c8063995bf45714610038575b5f5ffd5b61004b61004636600461121e565b610061565b6040516100589190611460565b60405180910390f35b610069610d80565b5f610078888888888886610128565b9083529050610087818961017c565b6020840191909152905061009b818461026b565b604084019190915290506100af8189610314565b606084019190915290506100c4888285610375565b608084019190915290506100d88882610444565b60a084019190915290506100ed888285610647565b60c084019190915290506101028882856107b9565b60e08401919091529050610116888261093b565b50610100830152509695505050505050565b610130610de5565b5f61013e8888888888610978565b60408601919091526020850191909152908352925061015d8389610c71565b6080850191909152606084019190915291989197509095505050505050565b610184610e15565b5f61018d610e34565b84815260e08401805151602080840191909152905181015160408084019190915261010086018051516060850152518201516080840152516101f0916101d591849101611535565b60405160208183030381529060405280519060200120610cfc565b91505f6101fc83610d22565b50808552905060015b6102116001601c61157c565b811015610261576102428561022760018461157c565b601b811061023757610237611521565b602002015183610d52565b8582601b811061025457610254611521565b6020020152600101610205565b5050509250929050565b610273610e52565b5f61028a846040516020016101d591815260200190565b935061029584610d22565b50825260015b8381101561030c576102ed836102b260018461157c565b601c81106102c2576102c2611521565b6020020151846102d360018561157c565b601c81106102e3576102e3611521565b6020020151610d52565b8382601c81106102ff576102ff611521565b602002015260010161029b565b509093915050565b5f5f61031e610e71565b84815261012084018051515160208084019190915290515181015160408084019190915261014086015160608401525161035e916101d59184910161158f565b915061036982610d22565b50959194509092505050565b61037d610e52565b5f805b8381101561043a57610390610e8f565b8581525f5b60098110156103f95787610160015183601c81106103b5576103b5611521565b602002015181600981106103cb576103cb611521565b6020020151826103dc8360016115c2565b600a81106103ec576103ec611521565b6020020152600101610395565b5061040e816040516020016101d591906115d5565b955061041986610d22565b508483601c811061042c5761042c611521565b602002015250600101610380565b5090949293505050565b5f5f61044e610eae565b83815260015b602981116104ab5761018086015161046d60018361157c565b6029811061047d5761047d611521565b602002015182826032811061049457610494611521565b6020020152806104a381611609565b915050610454565b856101a001518282603281106104c3576104c3611521565b60200201526104d36001826115c2565b61012087015160200151519091508282603281106104f3576104f3611521565b602002015261012086015160016020020151602001518282600161051791906115c2565b6032811061052757610527611521565b60200201526105376002826115c2565b610120870151604001515190915082826032811061055757610557611521565b602002015261012086015160026020020151602001518282600161057b91906115c2565b6032811061058b5761058b611521565b602002015261059b6002826115c2565b6101c0870151519091508282603281106105b7576105b7611521565b602002018181525050856101c0015160200151828260016105d891906115c2565b603281106105e8576105e8611521565b60200201526105f86002826115c2565b9050856101e0015182826032811061061257610612611521565b60200201818152505061062f826040516020016101d59190611621565b925061063a83610d22565b5096929550919350505050565b5f808061065560018561157c565b610660906002611655565b61066b9060016115c2565b6001600160401b0381111561068257610682610f09565b6040519080825280602002602001820160405280156106ab578160200160208202803683370190505b50905084815f815181106106c1576106c1611521565b60209081029190910101525f5b6106d960018661157c565b81101561078c5786610200015181601b81106106f7576106f7611521565b60200201515182610709836002611655565b6107149060016115c2565b8151811061072457610724611521565b60200260200101818152505086610200015181601b811061074757610747611521565b6020020151602001518282600261075e9190611655565b6107699060026115c2565b8151811061077957610779611521565b60209081029190910101526001016106ce565b506107a1816040516020016101d5919061166c565b91506107ac82610d22565b5096919550909350505050565b5f80806107c78460016115c2565b6107d29060046115c2565b6001600160401b038111156107e9576107e9610f09565b604051908082528060200260200182016040528015610812578160200160208202803683370190505b50905084815f8151811061082857610828611521565b602090810291909101015260015b8481116108925761022087015161084e60018361157c565b601c811061085e5761085e611521565b602002015182828151811061087557610875611521565b60209081029190910101528061088a81611609565b915050610836565b505f806108a08660016115c2565b90505b6108ae8660046115c2565b811161090d5787610240015182600481106108cb576108cb611521565b60200201518382815181106108e2576108e2611521565b6020908102919091010152816108f781611609565b925050808061090590611609565b9150506108a3565b50610922826040516020016101d5919061166c565b925061092d83610d22565b509792965091945050505050565b5f5f610945610ecd565b838152610260850180515160208084019190915290518101516040808401919091525161035e916101d591849101611696565b5f808080806109888660016115c2565b6109939060066115c2565b6001600160401b038111156109aa576109aa610f09565b6040519080825280602002602001820160405280156109d3578160200160208202803683370190505b509050865f1b815f815181106109eb576109eb611521565b60209081029190910101525f5b610a0360108861157c565b811015610a5457898982818110610a1c57610a1c611521565b9050602002013582826001610a3191906115c2565b81518110610a4157610a41611521565b60209081029190910101526001016109f8565b505f5b6010811015610ac5578a51610a7f908260108110610a7757610a77611521565b602002015190565b82826010610a8e8b60016115c2565b610a98919061157c565b610aa291906115c2565b81518110610ab257610ab2611521565b6020908102919091010152600101610a57565b5060208a01515181610ad88860016115c2565b81518110610ae857610ae8611521565b6020908102919091018101919091528a810151015181610b098860016115c2565b610b149060016115c2565b81518110610b2457610b24611521565b602090810291909101015260408a01515181610b418860016115c2565b610b4c9060026115c2565b81518110610b5c57610b5c611521565b60209081029190910181019190915260408b0151015181610b7e8860016115c2565b610b899060036115c2565b81518110610b9957610b99611521565b602090810291909101015260608a01515181610bb68860016115c2565b610bc19060046115c2565b81518110610bd157610bd1611521565b60209081029190910181019190915260608b0151015181610bf38860016115c2565b610bfe9060056115c2565b81518110610c0e57610c0e611521565b602002602001018181525050610c2e816040516020016101d5919061166c565b9150610c3982610d22565b6040805160208101869052929750909550610c5491016101d5565b9150610c5f82610d22565b50809350505095509550955095915050565b5f5f5f610c7c610eeb565b85815260a0858101805151602080850191909152905181015160408085019190915260c08089018051516060870152518301516080808701919091528901805151948601949094529251820151928401929092529051610ce2916101d5918491016116c9565b9150610ced82610d22565b90979096509194509092505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900690565b5f80826001600160801b038116608082901c610d3d82610cfc565b9450610d4881610cfc565b9350505050915091565b5f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182840990505b92915050565b604051806101400160405280610d94610de5565b8152602001610da1610e15565b8152602001610dae610e52565b81526020015f8152602001610dc1610e52565b81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b6040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b604051806103600160405280601b906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b6040518061064001604052806032906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060e001604052806007906020820280368337509192915050565b634e487b7160e01b5f52604160045260245ffd5b6040516102a081016001600160401b0381118282101715610f4057610f40610f09565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610f6e57610f6e610f09565b604052919050565b5f82601f830112610f85575f5ffd5b5f610200610f9281610f46565b915083018185821115610fa3575f5ffd5b845b82811015610fbd578035825260209182019101610fa5565b509195945050505050565b5f60408284031215610fd8575f5ffd5b604080519081016001600160401b0381118282101715610ffa57610ffa610f09565b604052823581526020928301359281019290925250919050565b5f82601f830112611023575f5ffd5b5f61102e6060610f46565b90508060c0840185811115611041575f5ffd5b845b81811015610fbd576110558782610fc8565b8352602090920191604001611043565b5f82601f830112611074575f5ffd5b61038061108081610f46565b905080611f80840185811115611094575f5ffd5b845b818110156110f85786601f8201126110ac575f5ffd5b5f6101206110b981610f46565b9150820181898211156110ca575f5ffd5b835b828110156110e45780358252602091820191016110cc565b505050845260209093019261012001611096565b509095945050505050565b5f82601f830112611112575f5ffd5b5f610520610f9281610f46565b5f82601f83011261112e575f5ffd5b5f61036061113b81610f46565b915050806106c0840185811115611150575f5ffd5b845b81811015610fbd576111648782610fc8565b8352602090920191604001611152565b5f82601f830112611183575f5ffd5b5f610380610f9281610f46565b5f82601f83011261119f575f5ffd5b5f6111aa6080610f46565b90508060808401858111156111bd575f5ffd5b845b81811015610fbd5780358352602092830192016111bf565b5f5f83601f8401126111e7575f5ffd5b5081356001600160401b038111156111fd575f5ffd5b6020830191508360208260051b8501011115611217575f5ffd5b9250929050565b5f5f5f5f5f5f8688036135c0811215611235575f5ffd5b613540811215611243575f5ffd5b5061124c610f1d565b6112568989610f76565b8152611266896102008a01610fc8565b6020820152611279896102408a01610fc8565b604082015261128c896102808a01610fc8565b606082015261129f896102c08a01610fc8565b60808201526112b2896103008a01610fc8565b60a08201526112c5896103408a01610fc8565b60c08201526112d8896103808a01610fc8565b60e08201526112eb896103c08a01610fc8565b6101008201526112ff896104008a01611014565b6101208201526104c088013561014082015261131f896104e08a01611065565b610160820152611333896124608a01611103565b6101808201526129808801356101a0820152611353896129a08a01610fc8565b6101c08201526129e08801356101e082015261137389612a008a0161111f565b610200820152611387896130c08a01611174565b61022082015261139b896134408a01611190565b6102408201526113af896134c08a01610fc8565b6102608201526113c3896135008a01610fc8565b61028082015295506135408701356001600160401b038111156113e4575f5ffd5b6113f089828a016111d7565b979a90995096976135608101359761358082013597506135a09091013595509350505050565b805f5b601b811015611438578151845260209384019390910190600101611419565b50505050565b805f5b601c811015611438578151845260209384019390910190600101611441565b8151805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a09081015190820152610be0810160208301516114af60c0840182611416565b5060408301516114c361042084018261143e565b5060608301516107a083015260808301516114e26107c084018261143e565b5060a0830151610b4083015260c0830151610b6083015260e0830151610b80830152610100830151610ba083015261012090920151610bc09091015290565b634e487b7160e01b5f52603260045260245ffd5b5f8183825b600581101561155957815183526020928301929091019060010161153a565b50505060a08201905092915050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d7a57610d7a611568565b5f8183825b60048110156115b3578151835260209283019290910190600101611594565b50505060808201905092915050565b80820180821115610d7a57610d7a611568565b5f8183825b600a8110156115f95781518352602092830192909101906001016115da565b5050506101408201905092915050565b5f6001820161161a5761161a611568565b5060010190565b5f8183825b6032811015611645578151835260209283019290910190600101611626565b5050506106408201905092915050565b8082028115828204841417610d7a57610d7a611568565b81515f90829060208501835b82811015610fbd578151845260209384019390910190600101611678565b5f8183825b60038110156116ba57815183526020928301929091019060010161169b565b50505060608201905092915050565b5f8183825b60078110156116ed5781518352602092830192909101906001016116ce565b50505060e0820190509291505056fea2646970667358221220e3db886c9c364c871b317bcb2e79e56ccdc97d6a569167c0c1670ecb2fd7d18064736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":7,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","networkInteractionId":1,"nonce":7,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40012000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x55d509a35e28242275f0daed764ae6cf03a60debbc27d2900dccca65b7c9f9be"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifierLib","hash":"0x68fd541e32966a4a4118ed562305e1dd7466f92750067ec81916351941c5452f","networkInteractionId":1,"receipt":{"blockHash":"0xf8d2ac64d2f4206e79456b4a70068bfdcd45cfd48c968e5e17e7d16575ad8675","blockNumber":233653870,"contractAddress":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifierLib","result":{"address":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","hash":"0xb72c8b03a42f378aafbbb40ebd77f6ba946ae72008be88d88ac969530683aae0","networkInteractionId":1,"receipt":{"blockHash":"0x43bcc943f2e2a342c852f363a226cb5a915e1c03a941af540cf77ca11da3d871","blockNumber":233653879,"contractAddress":"0xc246Abca0566848759dA29c30Fc77DC4A9962919","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferVerifierLib","result":{"address":"0xc246Abca0566848759dA29c30Fc77DC4A9962919","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifierLib","hash":"0x10463c715c3cf17a2bd738c072745e0868a7f1af07c25f920529fc3c46eaf091","networkInteractionId":1,"receipt":{"blockHash":"0x33385ce414367c367022fcccca326d28073578e73de1bb2837f04561ef3bd6e0","blockNumber":233653888,"contractAddress":"0x840feC4Efbd4764edAA237E78757cE59CeA3Db26","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifierLib","result":{"address":"0x840feC4Efbd4764edAA237E78757cE59CeA3Db26","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","hash":"0x55d509a35e28242275f0daed764ae6cf03a60debbc27d2900dccca65b7c9f9be","networkInteractionId":1,"receipt":{"blockHash":"0xbc5d14a57256b4afbebe4d38783fc2d7fdfc2ed5eff253ffc95c7a02eaeb403d","blockNumber":233653895,"contractAddress":"0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifierLib","result":{"address":"0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"depositVerifier#DepositVerifier","constructorArgs":[],"contractName":"DepositVerifier","dependencies":["depositVerifier#DepositVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"depositVerifier#DepositVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x9A0E3f3d11F7bA8B92faD4533043b5994615629d"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"depositVerifier#DepositVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50610100608052600860a0527f0de91f020abeb26e66cca710e3bd305d3b85bc9697faf94d737c82a7eeaf330b60c052601360e05260805160a05160c05160e051615ce66100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b950152612ebe01525f5050615ce65ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e7565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bf565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bf565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d6565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f90739A0E3f3d11F7bA8B92faD4533043b5994615629d9063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615759565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a92565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bf565b905061030a600260046155bf565b6103149082615b3c565b905060016103236009856155bf565b61032d91906155bf565b6103379082615b3c565b9050610345600160296155bf565b61034f9082615b3c565b905061035d600160036155bf565b6103679082615b3c565b90506103746001846155bf565b61037e9082615b3c565b905061038c600160046155bf565b6103969082615b3c565b905060026103a56001856155d6565b6103af91906155bf565b6103b99082615b3c565b90506103c66002806155bf565b6103d09082615b3c565b90506103dd601082615b3c565b9392505050565b6103ec615033565b6103f4611c0a565b905090565b6104016151bd565b5f805b60108110156104635761043086838761041e602083615b3c565b9261042b93929190615b4f565b612544565b8351826010811061044357610443615b76565b6020020181815250506020826104599190615b3c565b9150600101610404565b50610487858286610475604083615b3c565b9261048293929190615b4f565b612557565b6020830152610497604082615b3c565b90506104aa858286610475604083615b3c565b6040808401919091526104bd9082615b3c565b90506104d0858286610475604083615b3c565b60608301526104e0604082615b3c565b90506104f3858286610475604083615b3c565b60a0830152610503604082615b3c565b9050610516858286610475604083615b3c565b60c0830152610526604082615b3c565b9050610539858286610475604083615b3c565b6080830152610549604082615b3c565b905061055c858286610475604083615b3c565b60e083015261056c604082615b3c565b905061057f858286610475604083615b3c565b610100830152610590604082615b3c565b90506105a3858286610475604083615b3c565b610120830151526105b5604082615b3c565b90506105c885828661041e602083615b3c565b6101408301526105d9602082615b3c565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3c565b84610160015183601c811061061857610618615b76565b6020020151826009811061062e5761062e615b76565b6020020181815250506020836106449190615b3c565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3c565b836101800151826029811061068b5761068b615b76565b6020020181815250506020826106a19190615b3c565b915060010161065a565b506106bd85828661041e602083615b3c565b6101a08301526106ce602082615b3c565b90506106e1858286610475604083615b3c565b610120830151602001526106f6604082615b3c565b9050610709858286610475604083615b3c565b61012083015160026020020152610721604082615b3c565b9050610734858286610475604083615b3c565b6101c0830152610745604082615b3c565b905061075885828661041e602083615b3c565b6101e0830152610769602082615b3c565b90505f5b6107786001856155d6565b8110156107c157610790868387610475604083615b3c565b83610200015182601b81106107a7576107a7615b76565b60200201526107b7604083615b3c565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3c565b83610220015182601c81106107f4576107f4615b76565b60200201818152505060208261080a9190615b3c565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3c565b836102400151826004811061084857610848615b76565b60200201818152505060208261085e9190615b3c565b9150600101610817565b5061087a858286610475604083615b3c565b61026083015261088b604082615b3c565b905061089e858286610475604083615b3c565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3c565b6125d9565b6125f1565b61260c565b90505f6108f7876108f28a6108cf6108ca8b6001615b3c565b612625565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015610993575f6109508c838151811061094357610943615b76565b602002602001015161264d565b9050610960866108cf868461260c565b9550610970856108cf858461260c565b945061097c848b61260c565b9350610988838b612625565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b76565b602002015190506109c7866108cf868461260c565b95506109d7856108cf858461260c565b94506109e3848b61260c565b93506109ef838b612625565b925050600101610996565b50610a058484612662565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f1565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b76565b602002015180519091505f90610a8c908360015b602002015161260c565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b76565b60200201519050610ad68382612670565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b76565b60200201516001612625565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281e565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b76565b60200201516125f1565b9150600101610b3b565b50610bb7610ba4836108cf600185612625565b6108d4896101a0015189606001516125f1565b91508382145b979650505050505050565b5f610bd16152a6565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612897565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610c3a9190615b3c565b610c45906003615b3c565b6001600160401b03811115610c5c57610c5c615943565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b610cc09190615b3c565b610ccb906003615b3c565b6001600160401b03811115610ce257610ce2615943565b604051908082528060200260200182016040528015610d1b57816020015b610d08615316565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b76565b6020026020010151612625565b612960565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b76565b602002602001015161260c565b610140850181905261012085015160e0880151610da4926108d491906125f1565b845260c0860151610dd490610db890612960565b6108cf8661012001516108f28a60e001518961014001516125f1565b6020850152815160019083905f90610dee57610dee615b76565b602002602001018181525050876102600151815f81518110610e1257610e12615b76565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129d0565b60408501526020840151610e50906129d0565b60608501526040840151825183906001908110610e6f57610e6f615b76565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f1565b83610ea3836002615b3c565b81518110610eb357610eb3615b76565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b76565b60200201518860a001516125f1565b60c086015260a08086015190880151610f0991906125f1565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3c565b90505f610f3c602484615b3c565b9050610f6d858381518110610f5357610f53615b76565b60200260200101516108d489606001518a60a001516125f1565b858381518110610f7f57610f7f615b76565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b76565b60200201518a60a001516125f1565b60c088015260a080880151908a0151610fd591906125f1565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b76565b602002602001018190525086606001518160028151811061102157611021615b76565b602002602001018190525086608001518160038151811061104457611044615b76565b60200260200101819052508660a001518160048151811061106757611067615b76565b60200260200101819052508660c001518160058151811061108a5761108a615b76565b60200260200101819052508660e00151816006815181106110ad576110ad615b76565b6020026020010181905250866101000151816007815181106110d1576110d1615b76565b6020026020010181905250866101200151816008815181106110f5576110f5615b76565b60200260200101819052508661014001518160098151811061111957611119615b76565b602002602001018190525086610160015181600a8151811061113d5761113d615b76565b6020026020010181905250866101c0015181600b8151811061116157611161615b76565b602002602001018190525086610180015181600c8151811061118557611185615b76565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b76565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b76565b602002602001018190525086610200015181600f815181106111f1576111f1615b76565b60200260200101819052508661022001518160108151811061121557611215615b76565b60200260200101819052508661024001518160118151811061123957611239615b76565b60200260200101819052508661026001518160128151811061125d5761125d615b76565b60200260200101819052508661028001518160138151811061128157611281615b76565b6020026020010181905250866102a00151816014815181106112a5576112a5615b76565b6020026020010181905250866102c00151816015815181106112c9576112c9615b76565b6020026020010181905250866102e00151816016815181106112ed576112ed615b76565b60200260200101819052508661030001518160178151811061131157611311615b76565b60200260200101819052508661032001518160188151811061133557611335615b76565b60200260200101819052508661034001518160198151811061135957611359615b76565b602002602001018190525086610360015181601a8151811061137d5761137d615b76565b602002602001018190525086610380015181601b815181106113a1576113a1615b76565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b76565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b76565b6020026020010181905250876020015181601e8151811061140c5761140c615b76565b6020026020010181905250876040015181601f8151811061142f5761142f615b76565b602002602001018190525087606001518160208151811061145257611452615b76565b602002602001018190525087608001518160218151811061147557611475615b76565b60200260200101819052508761010001518160228151811061149957611499615b76565b60200260200101819052508760e00151816023815181106114bc576114bc615b76565b60200260200101819052508760a00151816024815181106114df576114df615b76565b60200260200101819052508760c001518160258151811061150257611502615b76565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e2565b9050611572815f8151811061155f5761155f615b76565b60200260200101518661012001516125f1565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f1565b8861014001516125f1565b608086015260e08701516115b690612b40565b60a08601525f6115c860246002615b3c565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d6565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d6565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3c565b81518110610d3c57610d3c615b76565b6101208901526101008a015161168e90610d49908961167e866001615b3c565b81518110610d7657610d76615b76565b61014089015260a08801516101208901516116a991906125f1565b61016089015260a088015160e08b01516116d1916116c6916125f1565b8961014001516125f1565b61018089018190526116f4906116e6906129d0565b6108d48a61016001516129d0565b866116ff8486615b3c565b8151811061170f5761170f615b76565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3c565b601c8110610b7d57610b7d615b76565b9050611782816108d48b6101600151888760016117659190615b3c565b8151811061177557611775615b76565b60200260200101516125f1565b905061179289608001518261260c565b60808a0152505b6117b86117ae8960a001518c60e001516125f1565b8b60e001516125f1565b60a08901526102008c015182601b81106117d4576117d4615b76565b6020020151856117e48486615b3c565b815181106117f4576117f4615b76565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d6565b61183e9082615b3c565b905061185e6118568961010001518a60c00151612625565b600190612662565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f1565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f1565b8960e001516125f1565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b76565b60200201518960a001516125f1565b9050611928816129d0565b886101000151836004811061193f5761193f615b76565b602002015260a088015160e08b015161195891906125f1565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b76565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b76565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3c565b815181106119ee576119ee615b76565b60209081029190910101526101008601516060015184611a0f836002615b3c565b81518110611a1f57611a1f615b76565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b76565b60200201518483611a5c81615b8a565b945081518110611a6e57611a6e615b76565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b76565b60200260200101819052508560800151848280611ac790615b8a565b935081518110611ad957611ad9615b76565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4b565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b76565b6020026020010181905250886101000151858381518110611b5f57611b5f615b76565b602002602001018181525050611b7361532e565b611b7d8587612eae565b8152611b8882612fca565b602082018190528c5182515f92611ba0929190613010565b90505f5f611bb08f5f0151613096565b91509150611bbd82613157565b611bc681613157565b8351611bd39083856131f6565b84526020840151611be59082856131f6565b602085018190528451611bf791613225565b9f9e505050505050505050505050505050565b611c12615033565b50604080516103e0810182526101008082526008602080840191909152601383850152835180850185527f0c610e16329f30d538dfe1083c326bd9f9a5390fb1f829757dda4737e10eb39b81527f2cf1dedb2404e8fb4e52aa24e475a4d78a477140d501163c5d5f36476a7bd7d2818301526060840152835180850185527f27ed7fa44ab1957b037a9daeb90e0ea62d042ff797f55160aa14a70cf507cf1481527f05383a5fa9dfb4dd4ca3dd76ad5154a0ad44f047f2ef3b9daea46679f0733a23818301526080840152835180850185527f149beac9c0009d60c525128331bb562050ff4a1b7de30cae1ff8ec2a283e0d5581527f0a4959d0af863bfd13dcb1ccc01b4234bd788e1d212e8d21b10f0c53c14243d18183015260a0840152835180850185527f1db2787999ce47c4f3cb4d87f789226a19654189e788f4a3b245a905d3f3017481527f29a06e16a5a506949a1ecf1b68733cf941016fafca12468327be5cfb07fb5e988183015260c0840152835180850185527f2e1ace28ef2395a3af9f76b271497aedac879045a377c783503206a3e1a2ce1d81527f21172164eb2e6b3503ee5222dac6084b6089bf76a4d108b8cc50368b2db73ad68183015260e0840152835180850185527f01102805e8a6696bb00634766e58ad9a9df28e863465213c082e077284b29c6181527f01f49d16c20bfc8edd2b2d970cc08a46620d9fae5c32e6b1260f7b2531f639d38183015291830191909152825180840184527e73e7c223dd4f3e4734c4d9d9c9df394bd2eee2e12bac2fc49429a0443ec8b081527f20fac57db30195c2427a75a4d67231c1d1c74c8f84f009ab21d3c88e9657403d81830152610120830152825180840184527f21d5898fe9b9f42b184fa59aacd629582b9da7d744b5a780301cd846aa22c03681527f02d9bdc7f18db8bd49c40473a9cc229b8f66f4ace7a859d7befb2cf33e8ea1e481830152610140830152825180840184527f2f9a7ffd477b4c93aa4d2517fb948d577a1627e60da9ff8bd85ab3f657523b1e81527f04aa96d8d949c7e69ef9891928e202a7ac6dac308f6fdf3ddff1af9e7732b71c81830152610160830152825180840184527f0c3d7ecface5a1c775e7c0aac5827ed5ca60cfb8ea743d2399d4921cbaf6be8881527f1dd7b73d84b8793468fb7c25e20de7cc4b20c1aac4c922dde28711401174d7aa81830152610180830152825180840184527f1242f67a5ff392e2e7f4a1be3df41a4d2cf6f7f05bbaead1adee08b86f1d1f7981527f05c55febcb9a66d697b5a491dba3a195a65158cdaaa92f724b5da912b53e7cd9818301526101a0830152825180840184527f13d47bff8c630e847b70e2732fd3f09b624fa65d1a24b7f14a8f25f3789622af81527f1a74ca4e118fb480b9b999902989a361d21663e93132f32921075f4c936a84df818301526101c0830152825180840184527f231dc2cdd10b54b4aaf4df5d649a02f4866e406c8148cdeb980af7da0fd8c25381527f0a66e2c0763068a029bb72eb6984de2ed40c8fc963fd68aacc9006d505377137818301526101e0830152825180840184527f090604c4619308dab621bacbc8b06e0293d14f744122061637b4e69454c530e581527f050cbeb8cc10bc2d3a2c20a13ed74df7a2b8ff1782c3d6460a46ab1d8d51d19081830152610200830152825180840184527f0a976bca86b5b61d73ecd79cc891dca431b3b57d2ad53a4da53da94b29721c3e81527f2ad247d9c05fec71230634ace895f6e59600a6ec0a4bc9e46ce3798dcf85d98181830152610220830152825180840184527f2ad93d7e4dbf30f0963da673a73a243251e506a4e358fd2bda5daba7ccc9888781527f1f1038708fba5a273057e40c670a2ed1df42279735e476e29e77d8ffec23562581830152610240830152825180840184527f0d420c35b8eb4612a5753451bf4dfcabc5d54ae2e9360898d6f17478dcf5d8ef81527f0e1bb0e901d897cdad7d37105d0c8b6268f094ebb99248f99cacedb5841c498281830152610260830152825180840184527f16af985d70c73522ee58b5ba9d301590f4d426e527762e01b04719eccc112daf81527f1e03cfd6366ad8e87599fd3fcc4033f94e90abb159df734722b691c9456b4da281830152610280830152825180840184527f14a1ff7e86e3f7aa97bdf6b50e7bcb8391ccf5ba043b40fbfc90a7915ad1b6ac81527f0beab901e25ac8d950f9c7520c2e7c14269d8650429a4f2082268f147389ffa3818301526102a0830152825180840184527f2f4ffca106bbae62a12d3817816b81a2f336b84e88e6022f71b787b9c7894d7f81527f198900c6c38f0335ccca8018093c472583005729a3035ab261f98511fed36186818301526102c0830152825180840184527f29a408238411ab963e2ca172c50b72161914c53a2529a4191176c25f213db27a81527f0448a2f87a5f5a571bc556b25d4d6005d1edbdc4fcfb6e29f7e9e31d121f224e818301526102e0830152825180840184527f20ab6a3b96ef991d763112257c636d68adb82735802af5d34031335f31d5033a81527f22233647ff6041657314664cf9f6f4945cad9ba1c45bd2ba24214979c0a5a90d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f17fe00102521241d0103984db7685af96b128a9b4d4855aefb29fd97a02f21b183527f2886c9076309190668520a010ccd0e3855a63c59468b284f5e6a3f07440b5ca5908301526103c081019190915290565b5f6103dd6125528385615ba2565b61264d565b61255f615316565b60408051808201909152805f516020615c715f395f51905f5261258560205f8789615b4f565b61258e91615ba2565b6125989190615bbf565b81526020908101905f516020615c715f395f51905f52906125bd906040908789615b4f565b6125c691615ba2565b6125d09190615bbf565b90529392505050565b5f5f516020615c915f395f51905f52825b0692915050565b5f5f516020615c915f395f51905f5282840990505b92915050565b5f5f516020615c915f395f51905f528284089392505050565b5f5f516020615c915f395f51905f52825f516020615c915f395f51905f520384089392505050565b5f5f516020615c915f395f51905f52826125ea565b5f6103dd836108cf84612960565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127695761275f826108cf8784612625565b9150600101612748565b50612772615341565b5f5b60098110156127c3576127a4610d4985836009811061279557612795615b76565b60200201516108cf8985612625565b8282600981106127b6576127b6615b76565b6020020152600101612774565b505f5b6009811015612809576127ff856108d48984600981106127e8576127e8615b76565b6020020151858560098110610b7d57610b7d615b76565b94506001016127c6565b5061281484836125f1565b9695505050505050565b5f612827615360565b612832868285613419565b61283e868683866135c5565b61284a868683866137b1565b6128558682856139d6565b612860868285613bca565b61286c86868386613f13565b6128778682856143bf565b6128828682856147d1565b61288d868285614b92565b6128148185614e92565b60605f826001600160401b038111156128b2576128b2615943565b6040519080825280602002602001820160405280156128db578160200160208202803683370190505b50905083815f815181106128f1576128f1615b76565b602090810291909101015260015b8381101561295857612933826129166001846155d6565b8151811061292657612926615b76565b6020026020010151612b40565b82828151811061294557612945615b76565b60209081029190910101526001016128ff565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c915f395f51905f520360808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa806129bc575f5ffd5b505f51608091909101604052949350505050565b5f516020615c915f395f51905f520390565b60605f826001600160401b038111156129fd576129fd615943565b604051908082528060200260200182016040528015612a26578160200160208202803683370190505b509050825b8015612b35575f85612a3e6001846155d6565b81518110612a4e57612a4e615b76565b602002602001015190505f89600184612a6791906155d6565b601c8110612a7757612a77615b76565b602002015190505f612ad2612a96612a8f858d6125f1565b60026125f1565b6108f28b612aa56001896155d6565b601c8110612ab557612ab5615b76565b60200201516108cf612acc886108cf60018a612625565b87612625565b9050612af3816108cf610d49612aed876108cf600189612625565b8661260c565b99508990508085612b056001876155d6565b81518110612b1557612b15615b76565b60200260200101818152505050505080612b2e90615bde565b9050612a2b565b509695505050505050565b5f61260682836125f1565b5f600181612b64612b5e87610100614eeb565b83612625565b905080612b845760405163835eb8f760e01b815260040160405180910390fd5b612b8c61537f565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c75575f612bc78260096155bf565b612bd2906001615b3c565b905084835f0151826101008110612beb57612beb615b76565b60200201525f612bfc826001615b3c565b90505b612c0a600983615b3c565b811015612c6b578351612c4a90612c226001846155d6565b6101008110612c3357612c33615b76565b60200201518a85601c8110610b7d57610b7d615b76565b8451826101008110612c5e57612c5e615b76565b6020020152600101612bff565b5050600101612b93565b50608081018390525f602082018190525b610100811015612d8657612ca7612ca183608001518a6125f1565b85612625565b8260a00151826101008110612cbe57612cbe615b76565b602002015260a0820151612ce890826101008110612cde57612cde615b76565b6020020151612960565b8260a00151826101008110612cff57612cff615b76565b602002018181525050612d4582602001516108d4845f0151846101008110612d2957612d29615b76565b60200201518560a00151856101008110610b7d57610b7d615b76565b60208301526080820151612d79907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f1565b6080830152600101612c86565b505f612d97836108cf610100612960565b9050612da78260200151826125f1565b602083015260a0820151612dc2905f5b6020020151826125f1565b604083015260a0820151612dee90612ddd60016101006155d6565b6101008110612db757612db7615b76565b60608301526040820151612e04908a6002610b7d565b60c08301819052612e64906108d4612e3c8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612625565b60208d015160408e01516108cf91612e5391612625565b8e5160208901516108f291906125f1565b60c083018190526060830151612e9991612e8d916108d4906108cf8e600260200201518c612625565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb6615316565b5f6003612ee47f00000000000000000000000000000000000000000000000000000000000000006024615b3c565b612eee9190615b3c565b612ef9906003615b3c565b90505f5b81811015612f2f57612f27858281518110612f1a57612f1a615b76565b6020026020010151613157565b600101612efd565b50604051600190815b60018401811015612f945760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f38565b5080518452602081015160208501525080612fc2576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd2615316565b5f516020615c715f395f51905f5282602001515f516020615c715f395f51905f52612ffd91906155d6565b6130079190615bbf565b60208301525090565b5f5f5f61301c86613096565b915091506130286153c3565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307b91849101615bf3565b6040516020818303038152906040528051906020012061264d565b61309e615316565b6130a6615316565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c715f395f51905f528380095f516020615c715f395f51905f5260035f516020615c715f395f51905f52838709085f516020615c715f395f51905f5284850914915050806131f05760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fe615316565b613206615316565b6132108386614f4c565b905061321c8185614fa2565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133bb9190615c27565b5f60405180830381855afa9150503d805f81146133f3576040519150601f19603f3d011682016040523d82523d5f602084013e6133f8565b606091505b50915091508180156128145750808060200190518101906128149190615c3d565b5f613425846007615003565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348661348061345a856003612625565b6108cf61347561346a8b5f615003565b6108cf8c601d615003565b6108cf8b601c615003565b836125f1565b90506135076134fc6134e36134ca6134b1856108d46134a68d6002615003565b6108cf8e601c615003565b6108d46134bf8c6003615003565b6108cf8d601d615003565b6108d46134d88b6004615003565b6108cf8c601e615003565b6108d46134f18a6005615003565b6108cf8b601f615003565b6108d4886001615003565b9050613526816108d461351b866001612625565b6108cf8a6027615003565b905061353281846125f1565b905061353e81856125f1565b8552505f905061357861356e61356361355888601c615003565b6108d489601f615003565b6108f2886024615003565b6108d4875f615003565b9050613589816108cf846002612625565b905061359a816108cf846001612625565b90506135a681836125f1565b90506135b281846125f1565b9050808460015b60200201525050505050565b5f5f5f6135fb6135f16135d989601c615003565b6108d46135e78b6012615003565b8a606001516125f1565b876080015161260c565b9050613634816108cf61362a6136128b601d615003565b6108d46136208d6013615003565b8c606001516125f1565b896080015161260c565b9050613659816108cf61362a61364b8b601e615003565b6108d46136208d6014615003565b905061367e816108cf61362a6136708b601f615003565b6108d46136208d6015615003565b92505f90506136a26135f161369489601c615003565b6108d46135e78b600e615003565b90506136c7816108cf61362a6136b98b601d615003565b6108d46136208d600f615003565b90506136ec816108cf61362a6136de8b601e615003565b6108d46136208d6010615003565b9050613711816108cf61362a6137038b601f615003565b6108d46136208d6011615003565b91505f9050613738613732613727896020615003565b6108d48a601a615003565b846125f1565b905061376d816108f261376761374f8b6028615003565b6108d461375d8d601b615003565b8c60a001516125f1565b856125f1565b905061377981856125f1565b6040860152505f61379c61376761379189601b615003565b6108cf8a6028615003565b9050808560035b602002015250505050505050565b5f5f61380f6137f76137df6137ca61362a8a6016615003565b6108d46137d88b6017615003565b8a516125f1565b6108d46137ed8a6018615003565b89602001516125f1565b6108d4613805896019615003565b88604001516125f1565b91505f61384661382d61382389601c615003565b886080015161260c565b6108d461383b8a6003615003565b6108cf8b6024615003565b90505f61386f61385789601d615003565b6108d46138648b5f615003565b6108cf8c6025615003565b90505f6138996138808a601e615003565b6108d461388e8c6001615003565b6108cf8d6026615003565b90506138d86138c06138b2856108d4868d5f01516125f1565b6108d4848c602001516125f1565b6108d46138ce8c6004615003565b8b604001516125f1565b93505050505f6138ec613732886021615003565b90505f6138fd613732896021615003565b90505f61393561391c6139118b6023615003565b6108d48c6006615003565b6108f261392a8c6023615003565b6108cf8d6006615003565b90505f613953612b5e61394887896125f1565b6108cf8d6021615003565b905061395f81886125f1565b90505f6139876139796139738d6006615003565b876125f1565b6108f26139738e6022615003565b90505f6139958c6023615003565b90505f6139a5612b5e83846125f1565b60808c0185905260a08c0184905290506139bf818b6125f1565b8b6006602002015250505050505050505050505050565b5f6139e25f6001612625565b90505f6139f05f6002612625565b90505f6139fe5f6003612625565b90505f613a1a613a0f88601d615003565b6108f289601c615003565b90505f613a36613a2b89601e615003565b6108f28a601d615003565b90505f613a52613a478a601f615003565b6108f28b601e615003565b90505f613a6e613a638b6024615003565b6108f28c601f615003565b905083613a7f816108cf818b61260c565b9050613a8f816108cf878a61260c565b9050613a9f816108cf878961260c565b9050613ab0816108cf8d6008615003565b9050613abc818a6125f1565b60e08b01525082613ad1816108cf818b61260c565b9050613ae1816108cf868a61260c565b9050613af1816108cf868961260c565b9050613b02816108cf8d6008615003565b9050613b0e818a6125f1565b6101008b01525081613b24816108cf818b61260c565b9050613b34816108cf858a61260c565b9050613b44816108cf858961260c565b9050613b55816108cf8d6008615003565b9050613b61818a6125f1565b6101208b01525080613b77816108cf818b61260c565b9050613b87816108cf848a61260c565b9050613b97816108cf848961260c565b9050613ba8816108cf8d6008615003565b9050613bb4818a6125f1565b610140909a019990995250505050505050505050565b613c036040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0e84601d615003565b8152613c1b84601e615003565b6020820152613c2b846024615003565b6040820152613c3b846027615003565b6060820152613c4b846026615003565b6080820152613c5b846025615003565b60a08201525f613c6c856002615003565b90505f613c79865f615003565b90505f613c8d8460400151855f0151612625565b90505f613ca2856020015186602001516125f1565b606086015190915086905f90613cb890806125f1565b90505f613cd6613cd089602001518a606001516125f1565b886125f1565b90505f613cf5613cee8a60a001518b6040015161260c565b8a5161260c565b9050613d0461397382886125f1565b9050613d2b613d25613d1f613d198487612625565b88612625565b8461260c565b8361260c565b9050613d53613d48613d3d83876125f1565b6108cf8f6009615003565b6108cf60018a612625565b6101608c015250505050602085015160808601515f91613d729161260c565b90505f613d90613d868860600151886125f1565b8860200151612625565b90505f613db4613da084876125f1565b6108d46137678b60a001518c5f0151612625565b9050613ddc613dd1613dc6838c6125f1565b6108cf8e6009615003565b6108cf600189612625565b6101808b0152505f9150613dfd9050613df683601161260c565b87516125f1565b90505f613e0a838461260c565b9050613e16818261260c565b90505f613e248360096125f1565b9050613e4d613e47613732613e408b60a001518c5f015161260c565b8b5161260c565b82612625565b60c089018190525f90613e6890613cd090613d3d908d6125f1565b9050613e7b8b600b60200201518261260c565b6101608c0152505086515f9250613ea29150613df690613e9b908061260c565b885161260c565b90505f613ee2613ebd836108cf8a5f01518b60a00151612625565b60208901516108f290613ed0908061260c565b6108cf8b602001518c6080015161260c565b9050613eff89600c60200201516108d4613cd0613d3d858d6125f1565b89600c602002015250505050505050505050565b613f7d604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f95613f8b86601e615003565b85604001516125f1565b808252613fb4906108d4613faa88601d615003565b87602001516125f1565b808252613fc9906108d4613df688601c615003565b808252613fdb906108d4876001615003565b80825260208201819052613ff4906108f287601f615003565b815261400f614004866024615003565b6108f287601c615003565b608082015261402d614022866027615003565b6108f287601f615003565b60608201526080810151614046906108cf816001612625565b6101c082015260808101516140869061407c90614075906108cf60015f516020615c915f395f51905f526155d6565b600161260c565b82606001516125f1565b60a082018190526140bc906140ae906108cf6140a3896002615003565b6108cf8a6003615003565b6108cf61376788600a615003565b83600e60200201526101c08101516140e0906140ae906108cf6140a3896002615003565b6101e08401528051614105906108cf6140fa886002615003565b6108cf896003615003565b6101208201525f61412461411a87601f615003565b8360200151612625565b9050614135816108cf836001612625565b60e0830152614152614148876026615003565b86604001516125f1565b60408301819052614175906108d461416b896025615003565b88602001516125f1565b60408301819052614195906108d461418e896024615003565b88516125f1565b60408301526141b26141a8876027615003565b8360400151612625565b60408301525f6141d16141c6886026615003565b6108f289601e615003565b90506142236141fe613480614075866080015160015f516020615c915f395f51905f526108cf91906155d6565b6108cf614075866040015160015f516020615c915f395f51905f526108cf91906155d6565b60c084015260408301516142459061423b90806125f1565b8460400151612625565b61010084015260c083015161427190614263906108cf8a6004615003565b6108cf6139738a600a615003565b6102008601526101c083015161429090614263906108cf8a6004615003565b6102208601526101008301516142af90614263906108cf8a6004615003565b61024086015260e08301516142c9906108cf896004615003565b6101408401526142e86142dd886025615003565b6108f289601d615003565b6101608401526080830151614326906141c69061431b90614075906108cf60015f516020615c915f395f51905f526155d6565b8561016001516125f1565b61018084018190526101208401516101a0850181905261435d916108d4906108cf6143528c6005615003565b6108cf8d6002615003565b6101a08401819052835161437d91906108d4906108cf6143528c5f615003565b6101a08401819052610140840151614395919061260c565b6101a084018190526143af906108cf6139738a600a615003565b6101a0840181905285600d6137a3565b6143f86040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442d61441461440986601c615003565b6108cf876025615003565b6108d4614422876024615003565b6108cf88601d615003565b815261447261446761444e61444387601c615003565b6108cf88601f615003565b6108d461445c88601d615003565b6108cf89601e615003565b6108f2866026615003565b6040820181905261448790600160441b6125f1565b6040820181905261449d906108f2866027615003565b6040820181905281516144b0919061260c565b604082018190526144c6906108cf866005615003565b604082015280516144db90600160441b6125f1565b8082526144fb906108d46144f0876024615003565b6108cf886025615003565b80825260208201819052614522906108f261451787601e615003565b6108d488601f615003565b60208201819052614538906108cf866004615003565b6020820152805160608201819052614555906108d486601f615003565b60608201819052614579906108f261456e876026615003565b6108d4886027615003565b6060820181905261458e906108cf865f615003565b8160600181815250505f6145b76145ad8360200151846040015161260c565b836060015161260c565b90506145c8816108cf876003615003565b90506145e06145d8866025615003565b6140006125f1565b608083018190526145f6906108d4876024615003565b60808301819052614609906140006125f1565b6080830181905261461f906108d487601e615003565b60808301819052614632906140006125f1565b60808301819052614648906108d487601d615003565b6080830181905261465b906140006125f1565b60808301819052614671906108d487601c615003565b60808301819052614687906108f287601f615003565b6080830181905261469d906108cf876005615003565b60808301526146b06145d8866026615003565b60a083018190526146c6906108d4876025615003565b60a083018190526146d9906140006125f1565b60a083018190526146ef906108d4876024615003565b60a08301819052614702906140006125f1565b60a08301819052614718906108d487601f615003565b60a0830181905261472b906140006125f1565b60a08301819052614741906108d487601e615003565b60a08301819052614757906108f2876027615003565b60a0830181905261476c906108cf875f615003565b60a0830181905260808301515f91614784919061260c565b9050614795816108cf886004615003565b90506147a1828261260c565b60c084018190526147ba906108cf61397389600b615003565b60c084018190528560136020020152505050505050565b6148476040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61486061485585601c615003565b6108d4866002615003565b815261487b61487085601d615003565b6108d4866003615003565b602082015261489961488e85601e615003565b6108d4866004615003565b60408201526148b76148ac85601f615003565b6108d4866005615003565b606082015280516148e9906148e2906148db906148d490806125f1565b84516125f1565b83516125f1565b82516125f1565b608082015260208101516149279061491d906149139061490990806125f1565b84602001516125f1565b83602001516125f1565b82602001516125f1565b60a082015260408101516149659061495b906149519061494790806125f1565b84604001516125f1565b83604001516125f1565b82604001516125f1565b60c082015260608101516149999061407c9061498f9061498590806125f1565b84606001516125f1565b83606001516125f1565b60e0820152608081015160a08201516149b2919061260c565b61010082015260c081015160e08201516149cc919061260c565b61012082015260a08101516149f0906149e5908061260c565b82610120015161260c565b61014082015260e0810151614a1490614a09908061260c565b82610100015161260c565b610160820152610120810151614a2a908061260c565b6101e08201819052614a4b90614a40908061260c565b82610160015161260c565b6101e0820152610100810151614a61908061260c565b6101a08201819052614a8290614a77908061260c565b82610140015161260c565b6101a08201819052610160820151614a999161260c565b6101808201526101408101516101e0820151614ab5919061260c565b6101c0820152614ac961348085600c615003565b6102008201819052610280840151610180830151614af4926108d4916108cf906108f28a6024615003565b8360146020020152614b2483601560200201516108d48361020001516108cf856101a001516108f28a6025615003565b8360156020020152614b5483601660200201516108d48361020001516108cf856101c001516108f28a6026615003565b8360166020020152614b8483601760200201516108d48361020001516108cf856101e001516108f28a6027615003565b836017602002015250505050565b614be46040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c197f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d9565b8152602001614c477f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d9565b8152602001614c747e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d9565b8152602001614ca27f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d9565b90529050614cbf614cb486601c615003565b6108d4876002615003565b6101208301819052614cfe90614cf390614ce890614cdd90806125f1565b8561012001516125f1565b8461012001516125f1565b8361012001516125f1565b8252614d0b85601d615003565b6020830152614d1b85601e615003565b6040830152614d2b85601f615003565b606083015281516020830151614d53916145ad91614d49919061260c565b846040015161260c565b6080830152614d6661373286600d615003565b6101408301528151614d8790614d7d90835f610b7d565b836080015161260c565b60a0830152614db384601860200201516108d48461014001516108cf8660a001516108f28b6024615003565b6103008501526020820151614dce90614d7d90836001610b7d565b60c0830152614dfa84601960200201516108d48461014001516108cf8660c001516108f28b6025615003565b6103208501526040820151614e1590614d7d90836002610b7d565b60e0830152614e4184601a60200201516108d48461014001516108cf8660e001516108f28b6026615003565b6103408501526060820151614e5c90614d7d90836003610b7d565b610100830152614e8a84601b60200201516108d48461014001516108cf8661010001516108f28b6027615003565b84601b6135b9565b815160015b601c811015614ee457614eda826108d48684601c8110614eb957614eb9615b76565b602002015186614eca6001876155d6565b601b8110610b7d57610b7d615b76565b9150600101614e97565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c915f395f51905f5260a082015260205f60c08360055afa80614f37575f5ffd5b505f5160809190910160405295945050505050565b614f54615316565b614f5c615316565b604051835181526020840151602082015284604082015260408160608360075afa80614f86575f5ffd5b5080518252602080820151908301526060016040529392505050565b614faa615316565b614fb2615316565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe7575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501757615017615c5c565b6029811061502757615027615b76565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615059615316565b8152602001615066615316565b8152602001615073615316565b8152602001615080615316565b815260200161508d615316565b815260200161509a615316565b81526020016150a7615316565b81526020016150b4615316565b81526020016150c1615316565b81526020016150ce615316565b81526020016150db615316565b81526020016150e8615316565b81526020016150f5615316565b8152602001615102615316565b815260200161510f615316565b815260200161511c615316565b8152602001615129615316565b8152602001615136615316565b8152602001615143615316565b8152602001615150615316565b815260200161515d615316565b815260200161516a615316565b8152602001615177615316565b8152602001615184615316565b8152602001615191615316565b815260200161519e615316565b81526020016151ab615316565b81526020016151b8615316565b905290565b604051806102a001604052806151d16153e2565b81526020016151de615316565b81526020016151eb615316565b81526020016151f8615316565b8152602001615205615316565b8152602001615212615316565b815260200161521f615316565b815260200161522c615316565b8152602001615239615316565b8152602001615246615401565b81526020015f815260200161525961542e565b815260200161526661545c565b81526020015f8152602001615279615316565b81526020015f815260200161528c61547b565b8152602001615299615360565b815260200161519e6154a9565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e46154a9565b81526020016152f16154a9565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151ab615316565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153926154c7565b81526020015f81526020015f81526020015f81526020015f81526020016153b76154c7565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615418615316565b8152602001906001900390816154105790505090565b604051806103800160405280601c905b615446615341565b81526020019060019003908161543e5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615493615316565b81526020019060019003908161548b5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154fa575f5ffd5b84356001600160401b0381111561550f575f5ffd5b8501601f8101871361551f575f5ffd5b80356001600160401b03811115615534575f5ffd5b876020828401011115615545575f5ffd5b6020918201955093508501356001600160401b03811115615564575f5ffd5b8501601f81018713615574575f5ffd5b80356001600160401b03811115615589575f5ffd5b8760208260051b840101111561559d575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612606576126066155ab565b81810381811115612606576126066155ab565b805f5b60108110156131f05781518452602093840193909101906001016155ec565b805f5b60038110156131f05761562c84835180518252602090810151910152565b604093909301926020919091019060010161560e565b805f5b601c8110156131f0578151845f5b6009811015615672578251825260209283019290910190600101615653565b505050610120939093019260209190910190600101615645565b805f5b60298110156131f057815184526020938401939091019060010161568f565b805f5b601b8110156131f0576156cf84835180518252602090810151910152565b60409390930192602091909101906001016156b1565b805f5b601c8110156131f05781518452602093840193909101906001016156e8565b805f5b60048110156131f057815184526020938401939091019060010161570a565b8183525f6001600160fb1b03831115615740575f5ffd5b8260051b80836020870137939093016020019392505050565b6157648188516155e9565b5f602088015161578261020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583461040084018261560b565b506101408801516104c08301526101608801516158556104e0840182615642565b5061018088015161586a61246084018261568c565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158af612a008401826156ae565b506102208801516158c46130c08401826156e5565b506102408801516158d9613440840182615707565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159229083018789615729565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597a5761597a615943565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a8576159a8615943565b604052919050565b5f60c082840312156159c0575f5ffd5b60405160c081016001600160401b03811182821017156159e2576159e2615943565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a33575f5ffd5b5f610360615a4081615980565b915083018185821115615a51575f5ffd5b845b82811015615a6b578051825260209182019101615a53565b509195945050505050565b5f82601f830112615a85575f5ffd5b5f610380615a4081615980565b5f610be0828403128015615aa4575f5ffd5b50615aad615957565b615ab784846159b0565b8152615ac68460c08501615a24565b6020820152615ad9846104208501615a76565b60408201526107a08301516060820152615af7846107c08501615a76565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612606576126066155ab565b5f5f85851115615b5d575f5ffd5b83861115615b69575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9b57615b9b6155ab565b5060010190565b80356020831015612606575f19602084900360031b1b1692915050565b5f82615bd957634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615bec57615bec6155ab565b505f190190565b5f8183825b6008811015615c17578151835260209283019290910190600101615bf8565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4d575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220d399c7b84ad489251f14c84ec9d7155f819cee9624a71993973a60e92edd696b64736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":8,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"depositVerifier#DepositVerifier","networkInteractionId":1,"nonce":8,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40012000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x8ce008102da62a7c9582b12bf67a9b1eccde28ec2a20df5ad89736de89c5c04f"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferExternalVerifier#TransferExternalVerifier","constructorArgs":[],"contractName":"TransferExternalVerifier","dependencies":["transferExternalVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferExternalVerifier#TransferExternalVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0xc246Abca0566848759dA29c30Fc77DC4A9962919"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f0a785e20a5da09f67c5d87eeca9cafeb709dd84839ca8b7097ffa4c4733a298860c052602360e05260805160a05160c05160e051615ce56100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b940152612ebd01525f5050615ce55ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e6565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155be565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155be565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d5565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073c246Abca0566848759dA29c30Fc77DC4A99629199063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615758565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a91565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155be565b905061030a600260046155be565b6103149082615b3b565b905060016103236009856155be565b61032d91906155be565b6103379082615b3b565b9050610345600160296155be565b61034f9082615b3b565b905061035d600160036155be565b6103679082615b3b565b90506103746001846155be565b61037e9082615b3b565b905061038c600160046155be565b6103969082615b3b565b905060026103a56001856155d5565b6103af91906155be565b6103b99082615b3b565b90506103c66002806155be565b6103d09082615b3b565b90506103dd601082615b3b565b9392505050565b6103ec615032565b6103f4611c0a565b905090565b6104016151bc565b5f805b60108110156104635761043086838761041e602083615b3b565b9261042b93929190615b4e565b612543565b8351826010811061044357610443615b75565b6020020181815250506020826104599190615b3b565b9150600101610404565b50610487858286610475604083615b3b565b9261048293929190615b4e565b612556565b6020830152610497604082615b3b565b90506104aa858286610475604083615b3b565b6040808401919091526104bd9082615b3b565b90506104d0858286610475604083615b3b565b60608301526104e0604082615b3b565b90506104f3858286610475604083615b3b565b60a0830152610503604082615b3b565b9050610516858286610475604083615b3b565b60c0830152610526604082615b3b565b9050610539858286610475604083615b3b565b6080830152610549604082615b3b565b905061055c858286610475604083615b3b565b60e083015261056c604082615b3b565b905061057f858286610475604083615b3b565b610100830152610590604082615b3b565b90506105a3858286610475604083615b3b565b610120830151526105b5604082615b3b565b90506105c885828661041e602083615b3b565b6101408301526105d9602082615b3b565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b3b565b84610160015183601c811061061857610618615b75565b6020020151826009811061062e5761062e615b75565b6020020181815250506020836106449190615b3b565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b3b565b836101800151826029811061068b5761068b615b75565b6020020181815250506020826106a19190615b3b565b915060010161065a565b506106bd85828661041e602083615b3b565b6101a08301526106ce602082615b3b565b90506106e1858286610475604083615b3b565b610120830151602001526106f6604082615b3b565b9050610709858286610475604083615b3b565b61012083015160026020020152610721604082615b3b565b9050610734858286610475604083615b3b565b6101c0830152610745604082615b3b565b905061075885828661041e602083615b3b565b6101e0830152610769602082615b3b565b90505f5b6107786001856155d5565b8110156107c157610790868387610475604083615b3b565b83610200015182601b81106107a7576107a7615b75565b60200201526107b7604083615b3b565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b3b565b83610220015182601c81106107f4576107f4615b75565b60200201818152505060208261080a9190615b3b565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b3b565b836102400151826004811061084857610848615b75565b60200201818152505060208261085e9190615b3b565b9150600101610817565b5061087a858286610475604083615b3b565b61026083015261088b604082615b3b565b905061089e858286610475604083615b3b565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b3b565b6125d8565b6125f0565b61260b565b90505f6108f7876108f28a6108cf6108ca8b6001615b3b565b612624565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015610993575f6109508c838151811061094357610943615b75565b602002602001015161264c565b9050610960866108cf868461260b565b9550610970856108cf858461260b565b945061097c848b61260b565b9350610988838b612624565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b75565b602002015190506109c7866108cf868461260b565b95506109d7856108cf858461260b565b94506109e3848b61260b565b93506109ef838b612624565b925050600101610996565b50610a058484612661565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125f0565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b75565b602002015180519091505f90610a8c908360015b602002015161260b565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b75565b60200201519050610ad6838261266f565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b75565b60200201516001612624565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281d565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b75565b60200201516125f0565b9150600101610b3b565b50610bb7610ba4836108cf600185612624565b6108d4896101a0015189606001516125f0565b91508382145b979650505050505050565b5f610bd16152a5565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612896565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610c3a9190615b3b565b610c45906003615b3b565b6001600160401b03811115610c5c57610c5c615942565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b610cc09190615b3b565b610ccb906003615b3b565b6001600160401b03811115610ce257610ce2615942565b604051908082528060200260200182016040528015610d1b57816020015b610d08615315565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b75565b6020026020010151612624565b61295f565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b75565b602002602001015161260b565b610140850181905261012085015160e0880151610da4926108d491906125f0565b845260c0860151610dd490610db89061295f565b6108cf8661012001516108f28a60e001518961014001516125f0565b6020850152815160019083905f90610dee57610dee615b75565b602002602001018181525050876102600151815f81518110610e1257610e12615b75565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cf565b60408501526020840151610e50906129cf565b60608501526040840151825183906001908110610e6f57610e6f615b75565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125f0565b83610ea3836002615b3b565b81518110610eb357610eb3615b75565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b75565b60200201518860a001516125f0565b60c086015260a08086015190880151610f0991906125f0565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b3b565b90505f610f3c602484615b3b565b9050610f6d858381518110610f5357610f53615b75565b60200260200101516108d489606001518a60a001516125f0565b858381518110610f7f57610f7f615b75565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b75565b60200201518a60a001516125f0565b60c088015260a080880151908a0151610fd591906125f0565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b75565b602002602001018190525086606001518160028151811061102157611021615b75565b602002602001018190525086608001518160038151811061104457611044615b75565b60200260200101819052508660a001518160048151811061106757611067615b75565b60200260200101819052508660c001518160058151811061108a5761108a615b75565b60200260200101819052508660e00151816006815181106110ad576110ad615b75565b6020026020010181905250866101000151816007815181106110d1576110d1615b75565b6020026020010181905250866101200151816008815181106110f5576110f5615b75565b60200260200101819052508661014001518160098151811061111957611119615b75565b602002602001018190525086610160015181600a8151811061113d5761113d615b75565b6020026020010181905250866101c0015181600b8151811061116157611161615b75565b602002602001018190525086610180015181600c8151811061118557611185615b75565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b75565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b75565b602002602001018190525086610200015181600f815181106111f1576111f1615b75565b60200260200101819052508661022001518160108151811061121557611215615b75565b60200260200101819052508661024001518160118151811061123957611239615b75565b60200260200101819052508661026001518160128151811061125d5761125d615b75565b60200260200101819052508661028001518160138151811061128157611281615b75565b6020026020010181905250866102a00151816014815181106112a5576112a5615b75565b6020026020010181905250866102c00151816015815181106112c9576112c9615b75565b6020026020010181905250866102e00151816016815181106112ed576112ed615b75565b60200260200101819052508661030001518160178151811061131157611311615b75565b60200260200101819052508661032001518160188151811061133557611335615b75565b60200260200101819052508661034001518160198151811061135957611359615b75565b602002602001018190525086610360015181601a8151811061137d5761137d615b75565b602002602001018190525086610380015181601b815181106113a1576113a1615b75565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b75565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b75565b6020026020010181905250876020015181601e8151811061140c5761140c615b75565b6020026020010181905250876040015181601f8151811061142f5761142f615b75565b602002602001018190525087606001518160208151811061145257611452615b75565b602002602001018190525087608001518160218151811061147557611475615b75565b60200260200101819052508761010001518160228151811061149957611499615b75565b60200260200101819052508760e00151816023815181106114bc576114bc615b75565b60200260200101819052508760a00151816024815181106114df576114df615b75565b60200260200101819052508760c001518160258151811061150257611502615b75565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129e1565b9050611572815f8151811061155f5761155f615b75565b60200260200101518661012001516125f0565b608086018190526102208a01515160e08901516115a392916108d49161159891906125f0565b8861014001516125f0565b608086015260e08701516115b690612b3f565b60a08601525f6115c860246002615b3b565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d5565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d5565b8210159050806117995761165e610d498b61010001518985600161164e9190615b3b565b81518110610d3c57610d3c615b75565b6101208901526101008a015161168e90610d49908961167e866001615b3b565b81518110610d7657610d76615b75565b61014089015260a08801516101208901516116a991906125f0565b61016089015260a088015160e08b01516116d1916116c6916125f0565b8961014001516125f0565b61018089018190526116f4906116e6906129cf565b6108d48a61016001516129cf565b866116ff8486615b3b565b8151811061170f5761170f615b75565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b3b565b601c8110610b7d57610b7d615b75565b9050611782816108d48b6101600151888760016117659190615b3b565b8151811061177557611775615b75565b60200260200101516125f0565b905061179289608001518261260b565b60808a0152505b6117b86117ae8960a001518c60e001516125f0565b8b60e001516125f0565b60a08901526102008c015182601b81106117d4576117d4615b75565b6020020151856117e48486615b3b565b815181106117f4576117f4615b75565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d5565b61183e9082615b3b565b905061185e6118568961010001518a60c00151612624565b600190612661565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125f0565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125f0565b8960e001516125f0565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b75565b60200201518960a001516125f0565b9050611928816129cf565b886101000151836004811061193f5761193f615b75565b602002015260a088015160e08b015161195891906125f0565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b75565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b75565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b3b565b815181106119ee576119ee615b75565b60209081029190910101526101008601516060015184611a0f836002615b3b565b81518110611a1f57611a1f615b75565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b75565b60200201518483611a5c81615b89565b945081518110611a6e57611a6e615b75565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b75565b60200260200101819052508560800151848280611ac790615b89565b935081518110611ad957611ad9615b75565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b4a565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b75565b6020026020010181905250886101000151858381518110611b5f57611b5f615b75565b602002602001018181525050611b7361532d565b611b7d8587612ead565b8152611b8882612fc9565b602082018190528c5182515f92611ba092919061300f565b90505f5f611bb08f5f0151613095565b91509150611bbd82613156565b611bc681613156565b8351611bd39083856131f5565b84526020840151611be59082856131f5565b602085018190528451611bf791613224565b9f9e505050505050505050505050505050565b611c12615032565b50604080516103e0810182526140008152600e602080830191909152602382840152825180840184527f23e623cc3bc94842c9285716c4daa7d94c95143008ce87a97e537f5368b955d981527f2bb88e2fac78f398cdca69ab6b6e35384b4db6c5862fed090e8b2f5add500a82818301526060830152825180840184527f11def2437fc9a903c3e89e578521c0169688f997f32fb245a1fbec922eaddccb81527f1da74e51d9b54bc508ddacb74a23b175b5ee32129b11860aaa572910f6673881818301526080830152825180840184527f282c60b1ffc17590008e1077cd3fffeecae48a1c802990ef698ac647070db74681527f0a2e36022511a3fd9eb5aa8736e1d86b3721e0e967c4ca7c7c69d9d2bb7466568183015260a0830152825180840184527f1d1eff831e8b4bbd4c2ba1ba8968d25325474043bd91890e09e17798d5aa3f4a81527f147086db350ce3d04a9b93bafc5733d92461a1a6c8c3db271b280cd90b33da0f8183015260c0830152825180840184527f26c2210867a306262558ef5cb1534aa31c9bcfda6bb6fca5bf4b5e316e30a2b281527f15bdbc8c0e80909235bb9dcf31c579ad75dcaf8e3530b35c2654bde0fe5db01f8183015260e0830152825180840184527f2540a7ce51da63dbd9723cad234c2d1a4bd3c6b6cbc0114b87703747844a5c5d81527f207e7c14f07e0a3359905280fe77c33dcae50f0c36fc31c438489a618318369d81830152610100830152825180840184527f1be7938c3cffdbf157d759bb3ae04f3cc776a575be660269b648847fa353cdf081527f299d896c0d5c22bdc41ef54284598342d1a1d6c70cf38b85106aa6afee38e24f81830152610120830152825180840184527f1941bfed3602b65d4c561850715ae5d956dbe53735e8ea4cb1147ff990d7cb2381527f0a1bea65672e20b919d4c00db4c1202004db342d5ae0d30fd8ba14137a34916081830152610140830152825180840184527f19a1e6ae48e6db1c71eb60aa93643532b97ee9c1530be63135c3495046f23d2a81527f0ea0dd5a6976d1df2848a0a1bc290f67e1b8bb03c9d9240b2cac93243b020d9581830152610160830152825180840184527f13b46d04ea9cfc6142913e9224d6d2e1cd864f06fea7217ec5fc89c1cdac915d81527f187d1e4e40925d67a394284dfe4974d031ecfaebf900b8573891ad83fb5e3f4681830152610180830152825180840184527f178d5b509013a94b753bb237acc58b78b01db87d24228a86eea8ead218a4f11281527f30287e635bda139039f9f7d5364da2b6519b89c6bbb865a9d266e422418d5a31818301526101a0830152825180840184527f27f56f63948ff46a875eee39322f5c822e018a2d271b05511d8c5490dff5efca81527f16fde0d7ac947d8268dd796712c25bfae9ae19cb4d7b7ad2a7d7619b43a6ffa3818301526101c0830152825180840184527f207d66292bcb16ded47a65674c835f936f73523a3656b1b50320cadfd5697b4381527f26a12239313af80e5da388844f3a5764411f189d76d69fc2ff3a311f5339b41f818301526101e0830152825180840184527f067ddc80491066dd57c9d28e5bb77882d6ef25500295d3a90225cf151708e19a81527f1396fb78d2125c861d26607bea993b3ec8e586f1c009c8903e61433b0052f82481830152610200830152825180840184527f25ba4a2f52ed83043c75c6bde8b16a2d123b444551aeb9f42bb1464cacfe59fa81527f27e5a0aa911ae3e3ad2484396a3f0f537475ee9782efa1bcf875cce08387a3ce81830152610220830152825180840184527f232150ec6309a12af692893129ab4f95c63daf58ea97b182f697fd42660669a381527f049c5faf3063aaec16d9f3ed5f4804c4e04407d9cc23f771bd783e337064ed9c81830152610240830152825180840184527f274ab963d8d16e8b46acf18e0347993e9eac644dbb049e142c8c17077389512481527f01bcfa8437a4e6a2b1bce6418a4a67ef7f7846a05c74b7e530452bd6c3ff6c8681830152610260830152825180840184527f2dfa05b6e21f947c304238d66d9a210c3c8b87ae53d13d39da67e154f5ba2d0381527f20a0e481909ab14112c5f8da8446ea223bc51c7815b0b854dfe45ba66579293481830152610280830152825180840184527f0242e44347b63d7b377582bd39bcb886cd5247a385299c4d727a3878a58e4c7681527f035f33f0d6fe460cf3bd3c4199b670f21e74eb216809a49831370892e621983b818301526102a0830152825180840184527f3044e0b267d48f3dcf05bcf12c4b63e98c3243adee2d768a9dd805746d209f2e81527f25e0061e404566c0ee7ebc89fd4dde9bc32b07c25bbeee52eefac4bf11874770818301526102c0830152825180840184527f0f401708c100d8f91eeacd6b2472717bd1bfa2e98947072b812ed6bb67b99c8881527f2f6fc111262af8d5d5a47da0920017303674c2361d7d7bfc44042dd9d113ab9b818301526102e0830152825180840184527f04930ba3427d925efc27b187eea287cf5ccce7337ea87a026433defd9ff9f58181527f0795d3193e440283934f574114e731ab44db8bb76b9d0add1299516d26aea6e981830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f2e9a985dbea7870116afd6f454e6c2fa44f15d36207939aa70b948a28b98f28d83527f1cdb68ba80b6599a0ab78f93d8bc2afcb6fb9d68375e6cca2fff0db2b235f71b908301526103c081019190915290565b5f6103dd6125518385615ba1565b61264c565b61255e615315565b60408051808201909152805f516020615c705f395f51905f5261258460205f8789615b4e565b61258d91615ba1565b6125979190615bbe565b81526020908101905f516020615c705f395f51905f52906125bc906040908789615b4e565b6125c591615ba1565b6125cf9190615bbe565b90529392505050565b5f5f516020615c905f395f51905f52825b0692915050565b5f5f516020615c905f395f51905f5282840990505b92915050565b5f5f516020615c905f395f51905f528284089392505050565b5f5f516020615c905f395f51905f52825f516020615c905f395f51905f520384089392505050565b5f5f516020615c905f395f51905f52826125e9565b5f6103dd836108cf8461295f565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127685761275e826108cf8784612624565b9150600101612747565b50612771615340565b5f5b60098110156127c2576127a3610d4985836009811061279457612794615b75565b60200201516108cf8985612624565b8282600981106127b5576127b5615b75565b6020020152600101612773565b505f5b6009811015612808576127fe856108d48984600981106127e7576127e7615b75565b6020020151858560098110610b7d57610b7d615b75565b94506001016127c5565b5061281384836125f0565b9695505050505050565b5f61282661535f565b612831868285613418565b61283d868683866135c4565b612849868683866137b0565b6128548682856139d5565b61285f868285613bc9565b61286b86868386613f12565b6128768682856143be565b6128818682856147d0565b61288c868285614b91565b6128138185614e91565b60605f826001600160401b038111156128b1576128b1615942565b6040519080825280602002602001820160405280156128da578160200160208202803683370190505b50905083815f815181106128f0576128f0615b75565b602090810291909101015260015b8381101561295757612932826129156001846155d5565b8151811061292557612925615b75565b6020026020010151612b3f565b82828151811061294457612944615b75565b60209081029190910101526001016128fe565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c905f395f51905f520360808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa806129bb575f5ffd5b505f51608091909101604052949350505050565b5f516020615c905f395f51905f520390565b60605f826001600160401b038111156129fc576129fc615942565b604051908082528060200260200182016040528015612a25578160200160208202803683370190505b509050825b8015612b34575f85612a3d6001846155d5565b81518110612a4d57612a4d615b75565b602002602001015190505f89600184612a6691906155d5565b601c8110612a7657612a76615b75565b602002015190505f612ad1612a95612a8e858d6125f0565b60026125f0565b6108f28b612aa46001896155d5565b601c8110612ab457612ab4615b75565b60200201516108cf612acb886108cf60018a612624565b87612624565b9050612af2816108cf610d49612aec876108cf600189612624565b8661260b565b99508990508085612b046001876155d5565b81518110612b1457612b14615b75565b60200260200101818152505050505080612b2d90615bdd565b9050612a2a565b509695505050505050565b5f61260582836125f0565b5f600181612b63612b5d87610100614eea565b83612624565b905080612b835760405163835eb8f760e01b815260040160405180910390fd5b612b8b61537e565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c74575f612bc68260096155be565b612bd1906001615b3b565b905084835f0151826101008110612bea57612bea615b75565b60200201525f612bfb826001615b3b565b90505b612c09600983615b3b565b811015612c6a578351612c4990612c216001846155d5565b6101008110612c3257612c32615b75565b60200201518a85601c8110610b7d57610b7d615b75565b8451826101008110612c5d57612c5d615b75565b6020020152600101612bfe565b5050600101612b92565b50608081018390525f602082018190525b610100811015612d8557612ca6612ca083608001518a6125f0565b85612624565b8260a00151826101008110612cbd57612cbd615b75565b602002015260a0820151612ce790826101008110612cdd57612cdd615b75565b602002015161295f565b8260a00151826101008110612cfe57612cfe615b75565b602002018181525050612d4482602001516108d4845f0151846101008110612d2857612d28615b75565b60200201518560a00151856101008110610b7d57610b7d615b75565b60208301526080820151612d78907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125f0565b6080830152600101612c85565b505f612d96836108cf61010061295f565b9050612da68260200151826125f0565b602083015260a0820151612dc1905f5b6020020151826125f0565b604083015260a0820151612ded90612ddc60016101006155d5565b6101008110612db657612db6615b75565b60608301526040820151612e03908a6002610b7d565b60c08301819052612e63906108d4612e3b8b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612624565b60208d015160408e01516108cf91612e5291612624565b8e5160208901516108f291906125f0565b60c083018190526060830151612e9891612e8c916108d4906108cf8e600260200201518c612624565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb5615315565b5f6003612ee37f00000000000000000000000000000000000000000000000000000000000000006024615b3b565b612eed9190615b3b565b612ef8906003615b3b565b90505f5b81811015612f2e57612f26858281518110612f1957612f19615b75565b6020026020010151613156565b600101612efc565b50604051600190815b60018401811015612f935760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f37565b5080518452602081015160208501525080612fc1576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fd1615315565b5f516020615c705f395f51905f5282602001515f516020615c705f395f51905f52612ffc91906155d5565b6130069190615bbe565b60208301525090565b5f5f5f61301b86613095565b915091506130276153c2565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307a91849101615bf2565b6040516020818303038152906040528051906020012061264c565b61309d615315565b6130a5615315565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c705f395f51905f528380095f516020615c705f395f51905f5260035f516020615c705f395f51905f52838709085f516020615c705f395f51905f5284850914915050806131ef5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fd615315565b613205615315565b61320f8386614f4b565b905061321b8185614fa1565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133ba9190615c26565b5f60405180830381855afa9150503d805f81146133f2576040519150601f19603f3d011682016040523d82523d5f602084013e6133f7565b606091505b50915091508180156128135750808060200190518101906128139190615c3c565b5f613424846007615002565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348561347f613459856003612624565b6108cf6134746134698b5f615002565b6108cf8c601d615002565b6108cf8b601c615002565b836125f0565b90506135066134fb6134e26134c96134b0856108d46134a58d6002615002565b6108cf8e601c615002565b6108d46134be8c6003615002565b6108cf8d601d615002565b6108d46134d78b6004615002565b6108cf8c601e615002565b6108d46134f08a6005615002565b6108cf8b601f615002565b6108d4886001615002565b9050613525816108d461351a866001612624565b6108cf8a6027615002565b905061353181846125f0565b905061353d81856125f0565b8552505f905061357761356d61356261355788601c615002565b6108d489601f615002565b6108f2886024615002565b6108d4875f615002565b9050613588816108cf846002612624565b9050613599816108cf846001612624565b90506135a581836125f0565b90506135b181846125f0565b9050808460015b60200201525050505050565b5f5f5f6135fa6135f06135d889601c615002565b6108d46135e68b6012615002565b8a606001516125f0565b876080015161260b565b9050613633816108cf6136296136118b601d615002565b6108d461361f8d6013615002565b8c606001516125f0565b896080015161260b565b9050613658816108cf61362961364a8b601e615002565b6108d461361f8d6014615002565b905061367d816108cf61362961366f8b601f615002565b6108d461361f8d6015615002565b92505f90506136a16135f061369389601c615002565b6108d46135e68b600e615002565b90506136c6816108cf6136296136b88b601d615002565b6108d461361f8d600f615002565b90506136eb816108cf6136296136dd8b601e615002565b6108d461361f8d6010615002565b9050613710816108cf6136296137028b601f615002565b6108d461361f8d6011615002565b91505f9050613737613731613726896020615002565b6108d48a601a615002565b846125f0565b905061376c816108f261376661374e8b6028615002565b6108d461375c8d601b615002565b8c60a001516125f0565b856125f0565b905061377881856125f0565b6040860152505f61379b61376661379089601b615002565b6108cf8a6028615002565b9050808560035b602002015250505050505050565b5f5f61380e6137f66137de6137c96136298a6016615002565b6108d46137d78b6017615002565b8a516125f0565b6108d46137ec8a6018615002565b89602001516125f0565b6108d4613804896019615002565b88604001516125f0565b91505f61384561382c61382289601c615002565b886080015161260b565b6108d461383a8a6003615002565b6108cf8b6024615002565b90505f61386e61385689601d615002565b6108d46138638b5f615002565b6108cf8c6025615002565b90505f61389861387f8a601e615002565b6108d461388d8c6001615002565b6108cf8d6026615002565b90506138d76138bf6138b1856108d4868d5f01516125f0565b6108d4848c602001516125f0565b6108d46138cd8c6004615002565b8b604001516125f0565b93505050505f6138eb613731886021615002565b90505f6138fc613731896021615002565b90505f61393461391b6139108b6023615002565b6108d48c6006615002565b6108f26139298c6023615002565b6108cf8d6006615002565b90505f613952612b5d61394787896125f0565b6108cf8d6021615002565b905061395e81886125f0565b90505f6139866139786139728d6006615002565b876125f0565b6108f26139728e6022615002565b90505f6139948c6023615002565b90505f6139a4612b5d83846125f0565b60808c0185905260a08c0184905290506139be818b6125f0565b8b6006602002015250505050505050505050505050565b5f6139e15f6001612624565b90505f6139ef5f6002612624565b90505f6139fd5f6003612624565b90505f613a19613a0e88601d615002565b6108f289601c615002565b90505f613a35613a2a89601e615002565b6108f28a601d615002565b90505f613a51613a468a601f615002565b6108f28b601e615002565b90505f613a6d613a628b6024615002565b6108f28c601f615002565b905083613a7e816108cf818b61260b565b9050613a8e816108cf878a61260b565b9050613a9e816108cf878961260b565b9050613aaf816108cf8d6008615002565b9050613abb818a6125f0565b60e08b01525082613ad0816108cf818b61260b565b9050613ae0816108cf868a61260b565b9050613af0816108cf868961260b565b9050613b01816108cf8d6008615002565b9050613b0d818a6125f0565b6101008b01525081613b23816108cf818b61260b565b9050613b33816108cf858a61260b565b9050613b43816108cf858961260b565b9050613b54816108cf8d6008615002565b9050613b60818a6125f0565b6101208b01525080613b76816108cf818b61260b565b9050613b86816108cf848a61260b565b9050613b96816108cf848961260b565b9050613ba7816108cf8d6008615002565b9050613bb3818a6125f0565b610140909a019990995250505050505050505050565b613c026040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0d84601d615002565b8152613c1a84601e615002565b6020820152613c2a846024615002565b6040820152613c3a846027615002565b6060820152613c4a846026615002565b6080820152613c5a846025615002565b60a08201525f613c6b856002615002565b90505f613c78865f615002565b90505f613c8c8460400151855f0151612624565b90505f613ca1856020015186602001516125f0565b606086015190915086905f90613cb790806125f0565b90505f613cd5613ccf89602001518a606001516125f0565b886125f0565b90505f613cf4613ced8a60a001518b6040015161260b565b8a5161260b565b9050613d0361397282886125f0565b9050613d2a613d24613d1e613d188487612624565b88612624565b8461260b565b8361260b565b9050613d52613d47613d3c83876125f0565b6108cf8f6009615002565b6108cf60018a612624565b6101608c015250505050602085015160808601515f91613d719161260b565b90505f613d8f613d858860600151886125f0565b8860200151612624565b90505f613db3613d9f84876125f0565b6108d46137668b60a001518c5f0151612624565b9050613ddb613dd0613dc5838c6125f0565b6108cf8e6009615002565b6108cf600189612624565b6101808b0152505f9150613dfc9050613df583601161260b565b87516125f0565b90505f613e09838461260b565b9050613e15818261260b565b90505f613e238360096125f0565b9050613e4c613e46613731613e3f8b60a001518c5f015161260b565b8b5161260b565b82612624565b60c089018190525f90613e6790613ccf90613d3c908d6125f0565b9050613e7a8b600b60200201518261260b565b6101608c0152505086515f9250613ea19150613df590613e9a908061260b565b885161260b565b90505f613ee1613ebc836108cf8a5f01518b60a00151612624565b60208901516108f290613ecf908061260b565b6108cf8b602001518c6080015161260b565b9050613efe89600c60200201516108d4613ccf613d3c858d6125f0565b89600c602002015250505050505050505050565b613f7c604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f94613f8a86601e615002565b85604001516125f0565b808252613fb3906108d4613fa988601d615002565b87602001516125f0565b808252613fc8906108d4613df588601c615002565b808252613fda906108d4876001615002565b80825260208201819052613ff3906108f287601f615002565b815261400e614003866024615002565b6108f287601c615002565b608082015261402c614021866027615002565b6108f287601f615002565b60608201526080810151614045906108cf816001612624565b6101c082015260808101516140859061407b90614074906108cf60015f516020615c905f395f51905f526155d5565b600161260b565b82606001516125f0565b60a082018190526140bb906140ad906108cf6140a2896002615002565b6108cf8a6003615002565b6108cf61376688600a615002565b83600e60200201526101c08101516140df906140ad906108cf6140a2896002615002565b6101e08401528051614104906108cf6140f9886002615002565b6108cf896003615002565b6101208201525f61412361411987601f615002565b8360200151612624565b9050614134816108cf836001612624565b60e0830152614151614147876026615002565b86604001516125f0565b60408301819052614174906108d461416a896025615002565b88602001516125f0565b60408301819052614194906108d461418d896024615002565b88516125f0565b60408301526141b16141a7876027615002565b8360400151612624565b60408301525f6141d06141c5886026615002565b6108f289601e615002565b90506142226141fd61347f614074866080015160015f516020615c905f395f51905f526108cf91906155d5565b6108cf614074866040015160015f516020615c905f395f51905f526108cf91906155d5565b60c084015260408301516142449061423a90806125f0565b8460400151612624565b61010084015260c083015161427090614262906108cf8a6004615002565b6108cf6139728a600a615002565b6102008601526101c083015161428f90614262906108cf8a6004615002565b6102208601526101008301516142ae90614262906108cf8a6004615002565b61024086015260e08301516142c8906108cf896004615002565b6101408401526142e76142dc886025615002565b6108f289601d615002565b6101608401526080830151614325906141c59061431a90614074906108cf60015f516020615c905f395f51905f526155d5565b8561016001516125f0565b61018084018190526101208401516101a0850181905261435c916108d4906108cf6143518c6005615002565b6108cf8d6002615002565b6101a08401819052835161437c91906108d4906108cf6143518c5f615002565b6101a08401819052610140840151614394919061260b565b6101a084018190526143ae906108cf6139728a600a615002565b6101a0840181905285600d6137a2565b6143f76040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442c61441361440886601c615002565b6108cf876025615002565b6108d4614421876024615002565b6108cf88601d615002565b815261447161446661444d61444287601c615002565b6108cf88601f615002565b6108d461445b88601d615002565b6108cf89601e615002565b6108f2866026615002565b6040820181905261448690600160441b6125f0565b6040820181905261449c906108f2866027615002565b6040820181905281516144af919061260b565b604082018190526144c5906108cf866005615002565b604082015280516144da90600160441b6125f0565b8082526144fa906108d46144ef876024615002565b6108cf886025615002565b80825260208201819052614521906108f261451687601e615002565b6108d488601f615002565b60208201819052614537906108cf866004615002565b6020820152805160608201819052614554906108d486601f615002565b60608201819052614578906108f261456d876026615002565b6108d4886027615002565b6060820181905261458d906108cf865f615002565b8160600181815250505f6145b66145ac8360200151846040015161260b565b836060015161260b565b90506145c7816108cf876003615002565b90506145df6145d7866025615002565b6140006125f0565b608083018190526145f5906108d4876024615002565b60808301819052614608906140006125f0565b6080830181905261461e906108d487601e615002565b60808301819052614631906140006125f0565b60808301819052614647906108d487601d615002565b6080830181905261465a906140006125f0565b60808301819052614670906108d487601c615002565b60808301819052614686906108f287601f615002565b6080830181905261469c906108cf876005615002565b60808301526146af6145d7866026615002565b60a083018190526146c5906108d4876025615002565b60a083018190526146d8906140006125f0565b60a083018190526146ee906108d4876024615002565b60a08301819052614701906140006125f0565b60a08301819052614717906108d487601f615002565b60a0830181905261472a906140006125f0565b60a08301819052614740906108d487601e615002565b60a08301819052614756906108f2876027615002565b60a0830181905261476b906108cf875f615002565b60a0830181905260808301515f91614783919061260b565b9050614794816108cf886004615002565b90506147a0828261260b565b60c084018190526147b9906108cf61397289600b615002565b60c084018190528560136020020152505050505050565b6148466040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485f61485485601c615002565b6108d4866002615002565b815261487a61486f85601d615002565b6108d4866003615002565b602082015261489861488d85601e615002565b6108d4866004615002565b60408201526148b66148ab85601f615002565b6108d4866005615002565b606082015280516148e8906148e1906148da906148d390806125f0565b84516125f0565b83516125f0565b82516125f0565b608082015260208101516149269061491c906149129061490890806125f0565b84602001516125f0565b83602001516125f0565b82602001516125f0565b60a082015260408101516149649061495a906149509061494690806125f0565b84604001516125f0565b83604001516125f0565b82604001516125f0565b60c082015260608101516149989061407b9061498e9061498490806125f0565b84606001516125f0565b83606001516125f0565b60e0820152608081015160a08201516149b1919061260b565b61010082015260c081015160e08201516149cb919061260b565b61012082015260a08101516149ef906149e4908061260b565b82610120015161260b565b61014082015260e0810151614a1390614a08908061260b565b82610100015161260b565b610160820152610120810151614a29908061260b565b6101e08201819052614a4a90614a3f908061260b565b82610160015161260b565b6101e0820152610100810151614a60908061260b565b6101a08201819052614a8190614a76908061260b565b82610140015161260b565b6101a08201819052610160820151614a989161260b565b6101808201526101408101516101e0820151614ab4919061260b565b6101c0820152614ac861347f85600c615002565b6102008201819052610280840151610180830151614af3926108d4916108cf906108f28a6024615002565b8360146020020152614b2383601560200201516108d48361020001516108cf856101a001516108f28a6025615002565b8360156020020152614b5383601660200201516108d48361020001516108cf856101c001516108f28a6026615002565b8360166020020152614b8383601760200201516108d48361020001516108cf856101e001516108f28a6027615002565b836017602002015250505050565b614be36040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c187f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d8565b8152602001614c467f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d8565b8152602001614c737e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d8565b8152602001614ca17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d8565b90529050614cbe614cb386601c615002565b6108d4876002615002565b6101208301819052614cfd90614cf290614ce790614cdc90806125f0565b8561012001516125f0565b8461012001516125f0565b8361012001516125f0565b8252614d0a85601d615002565b6020830152614d1a85601e615002565b6040830152614d2a85601f615002565b606083015281516020830151614d52916145ac91614d48919061260b565b846040015161260b565b6080830152614d6561373186600d615002565b6101408301528151614d8690614d7c90835f610b7d565b836080015161260b565b60a0830152614db284601860200201516108d48461014001516108cf8660a001516108f28b6024615002565b6103008501526020820151614dcd90614d7c90836001610b7d565b60c0830152614df984601960200201516108d48461014001516108cf8660c001516108f28b6025615002565b6103208501526040820151614e1490614d7c90836002610b7d565b60e0830152614e4084601a60200201516108d48461014001516108cf8660e001516108f28b6026615002565b6103408501526060820151614e5b90614d7c90836003610b7d565b610100830152614e8984601b60200201516108d48461014001516108cf8661010001516108f28b6027615002565b84601b6135b8565b815160015b601c811015614ee357614ed9826108d48684601c8110614eb857614eb8615b75565b602002015186614ec96001876155d5565b601b8110610b7d57610b7d615b75565b9150600101614e96565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c905f395f51905f5260a082015260205f60c08360055afa80614f36575f5ffd5b505f5160809190910160405295945050505050565b614f53615315565b614f5b615315565b604051835181526020840151602082015284604082015260408160608360075afa80614f85575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa9615315565b614fb1615315565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe6575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501657615016615c5b565b6029811061502657615026615b75565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615058615315565b8152602001615065615315565b8152602001615072615315565b815260200161507f615315565b815260200161508c615315565b8152602001615099615315565b81526020016150a6615315565b81526020016150b3615315565b81526020016150c0615315565b81526020016150cd615315565b81526020016150da615315565b81526020016150e7615315565b81526020016150f4615315565b8152602001615101615315565b815260200161510e615315565b815260200161511b615315565b8152602001615128615315565b8152602001615135615315565b8152602001615142615315565b815260200161514f615315565b815260200161515c615315565b8152602001615169615315565b8152602001615176615315565b8152602001615183615315565b8152602001615190615315565b815260200161519d615315565b81526020016151aa615315565b81526020016151b7615315565b905290565b604051806102a001604052806151d06153e1565b81526020016151dd615315565b81526020016151ea615315565b81526020016151f7615315565b8152602001615204615315565b8152602001615211615315565b815260200161521e615315565b815260200161522b615315565b8152602001615238615315565b8152602001615245615400565b81526020015f815260200161525861542d565b815260200161526561545b565b81526020015f8152602001615278615315565b81526020015f815260200161528b61547a565b815260200161529861535f565b815260200161519d6154a8565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e36154a8565b81526020016152f06154a8565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151aa615315565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e001604052806153916154c6565b81526020015f81526020015f81526020015f81526020015f81526020016153b66154c6565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615417615315565b81526020019060019003908161540f5790505090565b604051806103800160405280601c905b615445615340565b81526020019060019003908161543d5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615492615315565b81526020019060019003908161548a5790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f9575f5ffd5b84356001600160401b0381111561550e575f5ffd5b8501601f8101871361551e575f5ffd5b80356001600160401b03811115615533575f5ffd5b876020828401011115615544575f5ffd5b6020918201955093508501356001600160401b03811115615563575f5ffd5b8501601f81018713615573575f5ffd5b80356001600160401b03811115615588575f5ffd5b8760208260051b840101111561559c575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612605576126056155aa565b81810381811115612605576126056155aa565b805f5b60108110156131ef5781518452602093840193909101906001016155eb565b805f5b60038110156131ef5761562b84835180518252602090810151910152565b604093909301926020919091019060010161560d565b805f5b601c8110156131ef578151845f5b6009811015615671578251825260209283019290910190600101615652565b505050610120939093019260209190910190600101615644565b805f5b60298110156131ef57815184526020938401939091019060010161568e565b805f5b601b8110156131ef576156ce84835180518252602090810151910152565b60409390930192602091909101906001016156b0565b805f5b601c8110156131ef5781518452602093840193909101906001016156e7565b805f5b60048110156131ef578151845260209384019390910190600101615709565b8183525f6001600160fb1b0383111561573f575f5ffd5b8260051b80836020870137939093016020019392505050565b6157638188516155e8565b5f602088015161578161020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e083015261012088015161583361040084018261560a565b506101408801516104c08301526101608801516158546104e0840182615641565b5061018088015161586961246084018261568b565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ae612a008401826156ad565b506102208801516158c36130c08401826156e4565b506102408801516158d8613440840182615706565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c061354083018190526159219083018789615728565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597957615979615942565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a7576159a7615942565b604052919050565b5f60c082840312156159bf575f5ffd5b60405160c081016001600160401b03811182821017156159e1576159e1615942565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a32575f5ffd5b5f610360615a3f8161597f565b915083018185821115615a50575f5ffd5b845b82811015615a6a578051825260209182019101615a52565b509195945050505050565b5f82601f830112615a84575f5ffd5b5f610380615a3f8161597f565b5f610be0828403128015615aa3575f5ffd5b50615aac615956565b615ab684846159af565b8152615ac58460c08501615a23565b6020820152615ad8846104208501615a75565b60408201526107a08301516060820152615af6846107c08501615a75565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612605576126056155aa565b5f5f85851115615b5c575f5ffd5b83861115615b68575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9a57615b9a6155aa565b5060010190565b80356020831015612605575f19602084900360031b1b1692915050565b5f82615bd857634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615beb57615beb6155aa565b505f190190565b5f8183825b6008811015615c16578151835260209283019290910190600101615bf7565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4c575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a264697066735822122038679b3c7a3fce1a23478273a5a566ee81281d89103eaf2f55ae20d0971c491464736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":9,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","networkInteractionId":1,"nonce":9,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xa09b04e22f35f94e7ec3bbab24772cf75f7c3c602d56979da9334c988934fe10"},"type":"TRANSACTION_SEND"} +{"artifactId":"transferVerifier#TransferVerifier","constructorArgs":[],"contractName":"TransferVerifier","dependencies":["transferVerifier#TransferVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"transferVerifier#TransferVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x840feC4Efbd4764edAA237E78757cE59CeA3Db26"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"transferVerifier#TransferVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50614000608052600e60a0527f1c4077047ff8e779057f2c7bf723dcee6ef0858f21097b5d8a019c3bd991fdce60c052601760e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073840feC4Efbd4764edAA237E78757cE59CeA3Db269063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526140008152600e602080830191909152601782840152825180840184527f2a60a2ab5373757ac817380809610c107eec759a21662b952447a258181270fc81527f050521879e02eccc066e5858ddac7e843b4cce7df148f633444f614b9f500883818301526060830152825180840184527f05a4b5277bf006e4dd59032aef2bf29c5fe8feedbf6f3f2b7e794e46a594cd3d81527f2bf775553036a753722749a32ff39d4c8e5471b0eebf44cf0bc708824388a2a1818301526080830152825180840184527f145240d0368a33934b477affc8e697e1f13d15046446cc79219f4fbf643acfca81527f06b3bacd6e8c5fbc79238ca69fc0843b489849378842ebd551581a1a259e617a8183015260a0830152825180840184527e40a1e5b619194dbcf54697577ff0e0dee074d3d121101b99d7754bd5fa441b81527f165b55f16f7479be1c96431460633633cc719288e45a942a79c59fbb72dfca8d8183015260c0830152825180840184527f271d2bca125a5d9cbf34b75be5112706d2ebe76f7c913261701166cd99246f6981527f2ab0ebd5ffd78338afcd7a9214c8a4fc4236d760a3bdbd232f174af60d146b8c8183015260e0830152825180840184527f01571d27f44985f3d48bf4d53e578cfafd37590dcbcc62518625536ea15201be81527f1267a6f39e7db18a285e2429572fb228ef8284420bc4c7cb406eeb9261b3575f81830152610100830152825180840184527f1958b13f38f58756e23989a418de3c113d47a2256ba6f60a9e2ec0523c52a99181527f286c1d4c53af6654de284fbb620f90a9e00aa9470a9e3c58a56cc81e212df92381830152610120830152825180840184527f0b91dabfd35c5bd04ac1fb42131f8c3b33ff2c408f5b71ac243e19450695e79181527f1d6aec878349682265007d2f2182f3dcf6749430475f6a5af93383bbd5d3356a81830152610140830152825180840184527f2394a705d3639755270d10bfcdae31939ae587ddd45f22005c3b44f2392508d481527f035d98188439ee1621fbfbbb045e2f97f68273bad97f0940b9f0882dfad4fdb681830152610160830152825180840184527f13628822a94c01b9a8f7e8760f896a3594e7f2e39c2e33441ef7b5e9a6d189c381527f175bf4b8d19c57eb28ed35acb7520dd8adc99e5d47842fe066e26e80ec5884ce81830152610180830152825180840184527f1c26f826cfcda8b6f83feb6c3da00f9ae69733414e9cc7b4dd93dc1ae2f13f7181527f03da7aeba0324311534246e8b1b91370c5fb74a626494a5997b611fdf89a5e42818301526101a0830152825180840184527f229643b6b572f09479b16f379d26c93973fd172f88d2453bc0321f4239b76c6681527e37adfd4603991f5c8987c3787ee19f52b45f1632ecb04edf77ea34bab4a049818301526101c0830152825180840184527f139bbef00825b0f937a68d0da8e5235e320ccbfd02ad89b76b88ca805be5b4d681527f20d07c1a860aee3fe78dc8896ab77f7846364e81f3d182e2499cbaf684558b04818301526101e0830152825180840184527f175e34d1b2168e138d8a3a521ba7f63aaadee18a3ce82de85b15338773b2e06a81527f19cf85fc6f9830e17d1b1d5995ac39043fca45fa76ae59e397dd64868a93a6a881830152610200830152825180840184527f267269665b209a4cb03e205982b8b2e39f4abf77bad1a28e3a612c5216db7af681527f080918d08a0547a03a0431e4be01755d1a6307a9b772599b484d89aa26c449bc81830152610220830152825180840184527f13227e6690f2cf1b362b6686af9daceb8815f71fe316e396d5f81e8d5f30af1e81527f3032ba59ff8c42e446e1e34421fa6c832612e5a38e554272cfd619272652f04881830152610240830152825180840184527f222dbee14b833abc8ccabe2ca7420cad14941b04220e7130dd71c77dc0933ccf81527f0b3c88aface8f9d5232086d99f2d629d0a145bcfe25ba9f52dc0a95e9e4df31381830152610260830152825180840184527f0482cda528bbd9fa5d8e7868cbf4ed5529bfaaeb34a5de0daa68861fa7bf527b81527f1664b06cc3235ae6d7ccfd8d400d7265370c977227d73f52cdca8a6faaea278581830152610280830152825180840184527f1096b6f2a6ceff7ecb78350571f791ff8bbfff91c54661b89e0e3c9ccb66536f81527f0b706a30167c8fe79a2141a7ac61d81990cfb250807207707baf9911e43f1f78818301526102a0830152825180840184527f2fb35e1b30e9a01dc23eeaea433963053fd07ab92553790ebf4ee03af6d1109d81527f04cb1ab61b927016addf243346550908b552d8da77ed36ca6cdd56a50e4cf0c6818301526102c0830152825180840184527f243f2c7b0017064824ad01c96e88bed8fcaebc741feb02cd75e02e19e4f0cf6581527f26f52d6278059bd8e0287fbd6317032c97d101a7e9017b7cc6ca16575be7b07b818301526102e0830152825180840184527f10ca406af5bd2e93f9b3de69f255389b21de0cc91bd102aaff68275d3db640d981527f18cc11662f64b679e93323ce55b67146a535f2873ba5242f8b67ec084f1dc40d81830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f14eaab37b25018e3f6a66b06c80dd920910f68a9033c823b89df45e036a355f983527f26cc098c5bc1c20790a121a62bae1655894df4a7962e794750b8e20af6fae289908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220c939cb5753d89fbeed86417fcbc2bec581722287eb963553760acbb6d98a3f8764736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":10,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"transferVerifier#TransferVerifier","networkInteractionId":1,"nonce":10,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40528000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xf227357736e685850eb46a38f977bb127fd0ebd7af9a6cd2242459ba42d2daa5"},"type":"TRANSACTION_SEND"} +{"artifactId":"withdrawVerifier#WithdrawVerifier","constructorArgs":[],"contractName":"WithdrawVerifier","dependencies":["withdrawVerifier#WithdrawVerifierLib"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"withdrawVerifier#WithdrawVerifier","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{"ZKTranscriptLib":"0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815"},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteraction":{"data":"0x610100604052348015610010575f5ffd5b50611000608052600c60a0527f12621c8eced2f18534f79f9c635b12181e7f68b635db28ef71cfbc13016230bb60c052602060e05260805160a05160c05160e051615ce36100dc5f395f81816101b0015261090201525f61018e01525f8181605b01528181609401528181610101015281816101d201528181610a3001528181610b3d01528181610bdc01528181610c0a01528181610c9001528181611524015281816115d3015281816116060152818161181001528181612b920152612ebb01525f5050615ce35ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ea50d0e41461002d575b5f5ffd5b61004061003b3660046154e4565b610054565b604051901515815260200160405180910390f35b5f5f61007f7f00000000000000000000000000000000000000000000000000000000000000006102ee565b905061008c8160206155bc565b85146100ee577f0000000000000000000000000000000000000000000000000000000000000000856100bf8360206155bc565b6040516359895a5360e01b81526004810193909352602483019190915260448201526064015b60405180910390fd5b5f6100f76103e4565b90505f61012588887f00000000000000000000000000000000000000000000000000000000000000006103f9565b90506010826040015161013891906155d3565b85146101575760405163fa06659360e01b815260040160405180910390fd5b60405163995bf45760e01b81525f9073237eEeE66266c72DBb7Ee2Aa84811666cE4EB8159063995bf457906101fa9085908b908b907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600401615756565b610be060405180830381865af4158015610216573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023a9190615a8f565b905061028a8787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525050855185516060810151608090910151919350915060016108ac565b815160a0015261029a8282610a13565b6102b7576040516313f8744360e31b815260040160405180910390fd5b6102c2828483610bc8565b6102df576040516352ec174560e11b815260040160405180910390fd5b50600198975050505050505050565b5f806102fc600260086155bc565b905061030a600260046155bc565b6103149082615b39565b905060016103236009856155bc565b61032d91906155bc565b6103379082615b39565b9050610345600160296155bc565b61034f9082615b39565b905061035d600160036155bc565b6103679082615b39565b90506103746001846155bc565b61037e9082615b39565b905061038c600160046155bc565b6103969082615b39565b905060026103a56001856155d3565b6103af91906155bc565b6103b99082615b39565b90506103c66002806155bc565b6103d09082615b39565b90506103dd601082615b39565b9392505050565b6103ec615030565b6103f4611c0a565b905090565b6104016151ba565b5f805b60108110156104635761043086838761041e602083615b39565b9261042b93929190615b4c565b612541565b8351826010811061044357610443615b73565b6020020181815250506020826104599190615b39565b9150600101610404565b50610487858286610475604083615b39565b9261048293929190615b4c565b612554565b6020830152610497604082615b39565b90506104aa858286610475604083615b39565b6040808401919091526104bd9082615b39565b90506104d0858286610475604083615b39565b60608301526104e0604082615b39565b90506104f3858286610475604083615b39565b60a0830152610503604082615b39565b9050610516858286610475604083615b39565b60c0830152610526604082615b39565b9050610539858286610475604083615b39565b6080830152610549604082615b39565b905061055c858286610475604083615b39565b60e083015261056c604082615b39565b905061057f858286610475604083615b39565b610100830152610590604082615b39565b90506105a3858286610475604083615b39565b610120830151526105b5604082615b39565b90506105c885828661041e602083615b39565b6101408301526105d9602082615b39565b90505f5b83811015610657575f5b600981101561064e5761060187848861041e602083615b39565b84610160015183601c811061061857610618615b73565b6020020151826009811061062e5761062e615b73565b6020020181815250506020836106449190615b39565b92506001016105e7565b506001016105dd565b505f5b60298110156106ab5761067486838761041e602083615b39565b836101800151826029811061068b5761068b615b73565b6020020181815250506020826106a19190615b39565b915060010161065a565b506106bd85828661041e602083615b39565b6101a08301526106ce602082615b39565b90506106e1858286610475604083615b39565b610120830151602001526106f6604082615b39565b9050610709858286610475604083615b39565b61012083015160026020020152610721604082615b39565b9050610734858286610475604083615b39565b6101c0830152610745604082615b39565b905061075885828661041e602083615b39565b6101e0830152610769602082615b39565b90505f5b6107786001856155d3565b8110156107c157610790868387610475604083615b39565b83610200015182601b81106107a7576107a7615b73565b60200201526107b7604083615b39565b915060010161076d565b505f5b83811015610814576107dd86838761041e602083615b39565b83610220015182601c81106107f4576107f4615b73565b60200201818152505060208261080a9190615b39565b91506001016107c4565b505f5b60048110156108685761083186838761041e602083615b39565b836102400151826004811061084857610848615b73565b60200201818152505060208261085e9190615b39565b9150600101610817565b5061087a858286610475604083615b39565b61026083015261088b604082615b39565b905061089e858286610475604083615b39565b610280830152509392505050565b5f600180826108d9866108d4896108cf6108ca8a6310000000615b39565b6125d6565b6125ee565b612609565b90505f6108f7876108f28a6108cf6108ca8b6001615b39565b612622565b90505f5b61092660107f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015610993575f6109508c838151811061094357610943615b73565b602002602001015161264a565b9050610960866108cf8684612609565b9550610970856108cf8584612609565b945061097c848b612609565b9350610988838b612622565b9250506001016108fb565b505f5b60108110156109fa575f8a82601081106109b2576109b2615b73565b602002015190506109c7866108cf8684612609565b95506109d7856108cf8584612609565b94506109e3848b612609565b93506109ef838b612622565b925050600101610996565b50610a05848461265f565b9a9950505050505050505050565b5f5f610a2883606001518561014001516125ee565b905060015f5b7f0000000000000000000000000000000000000000000000000000000000000000811015610b1a575f86610160015182601c8110610a6e57610a6e615b73565b602002015180519091505f90610a8c908360015b6020020151612609565b9050848114610aae576040516313f8744360e31b815260040160405180910390fd5b5f876080015184601c8110610ac557610ac5615b73565b60200201519050610ad6838261266d565b9550610b0a856108cf60016108d4856108cf8e604001518b601c8110610afe57610afe615b73565b60200201516001612622565b9450505050806001019050610a2e565b505f610b34866101800151865f015187602001518561281b565b9050600160025b7f0000000000000000000000000000000000000000000000000000000000000000811015610b9157610b8782886080015183601c8110610b7d57610b7d615b73565b60200201516125ee565b9150600101610b3b565b50610bb7610ba4836108cf600185612622565b6108d4896101a0015189606001516125ee565b91508382145b979650505050505050565b5f610bd16152a3565b5f610c008460c001517f0000000000000000000000000000000000000000000000000000000000000000612894565b90505f6003610c307f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610c3a9190615b39565b610c45906003615b39565b6001600160401b03811115610c5c57610c5c615940565b604051908082528060200260200182016040528015610c85578160200160208202803683370190505b5090505f6003610cb67f00000000000000000000000000000000000000000000000000000000000000006024615b39565b610cc09190615b39565b610ccb906003615b39565b6001600160401b03811115610ce257610ce2615940565b604051908082528060200260200182016040528015610d1b57816020015b610d08615313565b815260200190600190039081610d005790505b509050610d4e610d49876101000151855f81518110610d3c57610d3c615b73565b6020026020010151612622565b61295d565b84610120018181525050610d83610d49876101000151855f81518110610d7657610d76615b73565b6020026020010151612609565b610140850181905261012085015160e0880151610da4926108d491906125ee565b845260c0860151610dd490610db89061295d565b6108cf8661012001516108f28a60e001518961014001516125ee565b6020850152815160019083905f90610dee57610dee615b73565b602002602001018181525050876102600151815f81518110610e1257610e12615b73565b60209081029190910101526101e088015160c085015260a080870151908501528351610e3d906129cd565b60408501526020840151610e50906129cd565b60608501526040840151825183906001908110610e6f57610e6f615b73565b60209081029190910101525f5b6024811015610f1657610e9785604001518660a001516125ee565b83610ea3836002615b39565b81518110610eb357610eb3615b73565b602002602001018181525050610ef08560c001516108d48b61018001518460298110610ee157610ee1615b73565b60200201518860a001516125ee565b60c086015260a08086015190880151610f0991906125ee565b60a0860152600101610e7c565b505f5b6005811015610fe4575f610f2e601e83615b39565b90505f610f3c602484615b39565b9050610f6d858381518110610f5357610f53615b73565b60200260200101516108d489606001518a60a001516125ee565b858381518110610f7f57610f7f615b73565b602002602001018181525050610fbc8760c001516108d48d61018001518460298110610fad57610fad615b73565b60200201518a60a001516125ee565b60c088015260a080880151908a0151610fd591906125ee565b60a08801525050600101610f19565b50876101c0015181600181518110610ffe57610ffe615b73565b602002602001018190525086606001518160028151811061102157611021615b73565b602002602001018190525086608001518160038151811061104457611044615b73565b60200260200101819052508660a001518160048151811061106757611067615b73565b60200260200101819052508660c001518160058151811061108a5761108a615b73565b60200260200101819052508660e00151816006815181106110ad576110ad615b73565b6020026020010181905250866101000151816007815181106110d1576110d1615b73565b6020026020010181905250866101200151816008815181106110f5576110f5615b73565b60200260200101819052508661014001518160098151811061111957611119615b73565b602002602001018190525086610160015181600a8151811061113d5761113d615b73565b6020026020010181905250866101c0015181600b8151811061116157611161615b73565b602002602001018190525086610180015181600c8151811061118557611185615b73565b6020026020010181905250866101a0015181600d815181106111a9576111a9615b73565b6020026020010181905250866101e0015181600e815181106111cd576111cd615b73565b602002602001018190525086610200015181600f815181106111f1576111f1615b73565b60200260200101819052508661022001518160108151811061121557611215615b73565b60200260200101819052508661024001518160118151811061123957611239615b73565b60200260200101819052508661026001518160128151811061125d5761125d615b73565b60200260200101819052508661028001518160138151811061128157611281615b73565b6020026020010181905250866102a00151816014815181106112a5576112a5615b73565b6020026020010181905250866102c00151816015815181106112c9576112c9615b73565b6020026020010181905250866102e00151816016815181106112ed576112ed615b73565b60200260200101819052508661030001518160178151811061131157611311615b73565b60200260200101819052508661032001518160188151811061133557611335615b73565b60200260200101819052508661034001518160198151811061135957611359615b73565b602002602001018190525086610360015181601a8151811061137d5761137d615b73565b602002602001018190525086610380015181601b815181106113a1576113a1615b73565b6020026020010181905250866103a0015181601c815181106113c5576113c5615b73565b6020026020010181905250866103c0015181601d815181106113e9576113e9615b73565b6020026020010181905250876020015181601e8151811061140c5761140c615b73565b6020026020010181905250876040015181601f8151811061142f5761142f615b73565b602002602001018190525087606001518160208151811061145257611452615b73565b602002602001018190525087608001518160218151811061147557611475615b73565b60200260200101819052508761010001518160228151811061149957611499615b73565b60200260200101819052508760e00151816023815181106114bc576114bc615b73565b60200260200101819052508760a00151816024815181106114df576114df615b73565b60200260200101819052508760c001518160258151811061150257611502615b73565b60200260200101819052505f61154887608001518660c001518b6102200151877f00000000000000000000000000000000000000000000000000000000000000006129df565b9050611572815f8151811061155f5761155f615b73565b60200260200101518661012001516125ee565b608086018190526102208a01515160e08901516115a392916108d49161159891906125ee565b8861014001516125ee565b608086015260e08701516115b690612b3d565b60a08601525f6115c860246002615b39565b90505f5b6115f760017f00000000000000000000000000000000000000000000000000000000000000006155d3565b811015611808575f61162a60017f00000000000000000000000000000000000000000000000000000000000000006155d3565b8210159050806117995761165e610d498b61010001518985600161164e9190615b39565b81518110610d3c57610d3c615b73565b6101208901526101008a015161168e90610d49908961167e866001615b39565b81518110610d7657610d76615b73565b61014089015260a08801516101208901516116a991906125ee565b61016089015260a088015160e08b01516116d1916116c6916125ee565b8961014001516125ee565b61018089018190526116f4906116e6906129cd565b6108d48a61016001516129cd565b866116ff8486615b39565b8151811061170f5761170f615b73565b6020026020010181815250505f6117488961018001518e61022001518560016117389190615b39565b601c8110610b7d57610b7d615b73565b9050611782816108d48b6101600151888760016117659190615b39565b8151811061177557611775615b73565b60200260200101516125ee565b9050611792896080015182612609565b60808a0152505b6117b86117ae8960a001518c60e001516125ee565b8b60e001516125ee565b60a08901526102008c015182601b81106117d4576117d4615b73565b6020020151856117e48486615b39565b815181106117f4576117f4615b73565b6020908102919091010152506001016115cc565b5061183460017f00000000000000000000000000000000000000000000000000000000000000006155d3565b61183e9082615b39565b905061185e6118568961010001518a60c00151612622565b60019061265f565b60e08701515261010088015160c08901516118a291611856916108f2907f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76906125ee565b60e0878101805160200192909252815180516040909101529051805160609091015260a0870151908901516118e4916118da916125ee565b8960e001516125ee565b60a08701525f5b6004811015611992575f61191d8860e00151836004811061190e5761190e615b73565b60200201518960a001516125ee565b9050611928816129cd565b886101000151836004811061193f5761193f615b73565b602002015260a088015160e08b015161195891906125ee565b8860a001818152505061198488608001516108d4838f61024001518660048110610b7d57610b7d615b73565b6080890152506001016118eb565b506101008601515184518590839081106119ae576119ae615b73565b602090810291909101810191909152610100870151908101516119d2916002610a82565b846119de836001615b39565b815181106119ee576119ee615b73565b60209081029190910101526101008601516060015184611a0f836002615b39565b81518110611a1f57611a1f615b73565b60209081029190910101525f5b6003811015611a81578a61012001518160038110611a4c57611a4c615b73565b60200201518483611a5c81615b87565b945081518110611a6e57611a6e615b73565b6020908102919091010152600101611a2c565b506040518060400160405280600181526020016002815250838281518110611aab57611aab615b73565b60200260200101819052508560800151848280611ac790615b87565b935081518110611ad957611ad9615b73565b602002602001018181525050611b038a61024001518960c001518a608001518d6101a00151612b48565b611b205760405163a2a2ac8360e01b815260040160405180910390fd5b5f8a6102800151905080848381518110611b3c57611b3c615b73565b6020026020010181905250886101000151858381518110611b5f57611b5f615b73565b602002602001018181525050611b7361532b565b611b7d8587612eab565b8152611b8882612fc7565b602082018190528c5182515f92611ba092919061300d565b90505f5f611bb08f5f0151613093565b91509150611bbd82613154565b611bc681613154565b8351611bd39083856131f3565b84526020840151611be59082856131f3565b602085018190528451611bf791613222565b9f9e505050505050505050505050505050565b611c12615030565b50604080516103e0810182526110008152600c602080830191909152818301819052825180840184527f0c0ab0666d82bfced8aad792d8b1ae9c1bfef2237e6fd0b1c0bc9bd0fa0666d881527f062d12422538f339a2ddb06580e5094e066d28980bf4a85925523edb5c400be8818301526060830152825180840184527f034b14da543dfbceb12a33630815beeaac0d421867fcac77a66c106b2a73cd0d81527f08d4a04fa197925a3fcb1998b1eb0fb4280bef699d49c665c43a7cfa4c725b6b818301526080830152825180840184527f29dffba53f9cb1821317cb794f45273b4cad6bdd0a1a0f3555f1a98fd9a1d0b381527f074a5c6d39a9d75014f795ea558c8a5c886057f8b793311662ad6f1c6270d3378183015260a0830152825180840184527f0b48b338a211229bcda30d0042bdd105b762030ea7d04cda10fbe1ac990a1bf281527f0a5eaeec1d35a65ca4e7a367bf240446ad7dad3465c615546e5935634d0b8dab8183015260c0830152825180840184527f26cab2d1ca615da58ebac303b6b1691f58749be637468152fd4175f3d30730b881527f2d03caa33aeeab0ac15081d85260ab712ada193ce87ebc6dea5f06cca8f0f8ed8183015260e0830152825180840184527f1e6560a4c45405aae66601ab7cfe2f4cacac28060c04aee2c5ba36739a4f616b81527f058b6fdeddb4f8f87c88de46c1ed9a94a47e5617216312a2ea30c7b5b03a588a81830152610100830152825180840184527f0b1f36d8d9ae897751580a6339e07087f168ef4f156846c2dfaf6f3137d55c0881527f2928c90277b44c75e71e1375358368c18fc8615767a7a06fc0adab5712b29bcf81830152610120830152825180840184527f062954bf8ea7cc3317cbef9efdadd70f30b538edeeb23ef68f1a7f63034badf881527f07049f50e318db8035502f3a3da2751bf9f86e148267680077eda3bb31e789de81830152610140830152825180840184527f2af0bb4887182d0399bdc54049a4ae5ea24a09360dae12bdb980628a026062a481527f05d526a36f1e7ea7fb2e5ae0d390b16104fe627989ae586e21ea7a4f6a5d78cc81830152610160830152825180840184527f2feda4b6d4258a40958c0a790648e5e50697e73f6c0ad83b42e278df2e687eda81527e05c8de6a9f0ac97499e7893aa9de26ebfa2f06a4dee2b5a5078c100aa5360b81830152610180830152825180840184527f2efa527e424638d8fb7c17ee0a7a3d879856bfe167610b91f6385d756ef6a1d681527f193e87410e0cef4e8eda92393e5c89be4c28ea511c5b57e287c18e0124dccf51818301526101a0830152825180840184527f0f1c406fd595193daff097658f5ee75e82c6d5fb3bd4d7b5788429a9dbc628c781527f283183591c64b04b6fb827c8e06b882c9ca132ab14e19903fafee87d122b1e65818301526101c0830152825180840184527f20cb19167e371f60f9b86877d25f1957f14d1fb0b1c44834981dcf63189c9f7c81527f158c5c268fef8ee42cf6098b4db64d97cf0cd33b5e7e478e911276500cfe582f818301526101e0830152825180840184527f04d00a730095c3664508128fab6e002889fa2e85676b2c7252dd467d61cb04f381527ece217cb86461550089b6c3157b4f498091b61fcbd5061517be9ce6dc6abba181830152610200830152825180840184527f275a656588b6e2fa9a79a0a9586add14de799fc9748a1dea86b0bf9a95e755ca81527f22c5027d65efb69eff02021a7a424c543c4436322c8b7daa9f262ba06f3ca11981830152610220830152825180840184527f186e16e7ad67a39dd353b8442b9aae7ffc0845f2c0bd5bda9e151cfe18310b3881527f0b5a1727b3cc4d47c6c468324c259203a7be02d22ad850eb0c48b2207b8c195d81830152610240830152825180840184527f19f28e52d0cf4d6bf2310fb3c6378a57b734456cd1a978c27e27f9e641e28c0d81527f041c3ec90b18915d8293c0c0a19a13e46b60ddcf811bcd8104db98aa7bcc8ba281830152610260830152825180840184527f117be2e022049bcfcb493dfdaa74df4458251deab7a8147e5a028ec1c542aeee81527f2689abc965555c7f646825d66c16e6e4bf94c036410c42fdbabc968d4b60219b81830152610280830152825180840184527f20604964d5f7af8214231def60866f5cb03740143ca3cdd54a144076bfae61f881527f2e460ec85e5f940f277bbb53d2b81c16ab0500ec60d3d367b907940e0c0fa89e818301526102a0830152825180840184527f1a87f1923b27fefc9d46f46c660b3fb909ddb372d2a3e90e093e7bc5bd2e8f2081527f0e97b092a06935e4f880a2c3db757c251dadc1b1e1681b4b3c9520eca782ca29818301526102c0830152825180840184527f2a3eb8ecb67b2623b8201266df9a9cc8a8f4116eb7bf0d837207d961048da01981527f13363adfc91e90aa47459c23a2af885afb6aaf9043abaed15da241b0b8a05635818301526102e0830152825180840184527f24d87ed4487bfe3a56ff07322e10a2a0efb50dd4756bc73d36cc3204364005fe81527f1e77f9912ed564297a87776a54a791274750acf68c3196328b077b6f8389ba2381830152610300830152825180840184527f099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d2681527e15b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f81830152610320830152825180840184527f1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e81527f305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d1981830152610340830152825180840184527f13567e3b915c81013ada15236ba5cfa60111b440400b2bca37e2b1085e924a7781527f0148d22589b91f0d8f4674af5744dedafd63caea904b434e748f9713de8cc3d781830152610360830152825180840184527f043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce81527f261522c4089330646aff96736194949330952ae74c573d1686d9cb4a007338548183015261038083015282518084018452600181526002818301526103a083015282518084019093527f26e4f54a587cd5a3fc65b139de71a3aff263b603f438d973f3b8dabc120fb23e83527f04938e653a6ec753fb73938764d71bd50f372367aa8e527016df40ee0c91ccac908301526103c081019190915290565b5f6103dd61254f8385615b9f565b61264a565b61255c615313565b60408051808201909152805f516020615c6e5f395f51905f5261258260205f8789615b4c565b61258b91615b9f565b6125959190615bbc565b81526020908101905f516020615c6e5f395f51905f52906125ba906040908789615b4c565b6125c391615b9f565b6125cd9190615bbc565b90529392505050565b5f5f516020615c8e5f395f51905f52825b0692915050565b5f5f516020615c8e5f395f51905f5282840990505b92915050565b5f5f516020615c8e5f395f51905f528284089392505050565b5f5f516020615c8e5f395f51905f52825f516020615c8e5f395f51905f520384089392505050565b5f5f516020615c8e5f395f51905f52826125e7565b5f6103dd836108cf8461295d565b5f5f604051806101200160405280619d8081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd31815260200161024081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3181526020016105a081526020017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec518152602001619d8081525090505f600190505f5f90505b60098110156127665761275c826108cf8784612622565b9150600101612745565b5061276f61533e565b5f5b60098110156127c0576127a1610d4985836009811061279257612792615b73565b60200201516108cf8985612622565b8282600981106127b3576127b3615b73565b6020020152600101612771565b505f5b6009811015612806576127fc856108d48984600981106127e5576127e5615b73565b6020020151858560098110610b7d57610b7d615b73565b94506001016127c3565b5061281184836125ee565b9695505050505050565b5f61282461535d565b61282f868285613416565b61283b868683866135c2565b612847868683866137ae565b6128528682856139d3565b61285d868285613bc7565b61286986868386613f10565b6128748682856143bc565b61287f8682856147ce565b61288a868285614b8f565b6128118185614e8f565b60605f826001600160401b038111156128af576128af615940565b6040519080825280602002602001820160405280156128d8578160200160208202803683370190505b50905083815f815181106128ee576128ee615b73565b602090810291909101015260015b8381101561295557612930826129136001846155d3565b8151811061292357612923615b73565b6020026020010151612b3d565b82828151811061294257612942615b73565b60209081029190910101526001016128fc565b509392505050565b5f5f8290505f604051602081526020808201526020604082015282606082015260025f516020615c8e5f395f51905f520360808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa806129b9575f5ffd5b505f51608091909101604052949350505050565b5f516020615c8e5f395f51905f520390565b60605f826001600160401b038111156129fa576129fa615940565b604051908082528060200260200182016040528015612a23578160200160208202803683370190505b509050825b8015612b32575f85612a3b6001846155d3565b81518110612a4b57612a4b615b73565b602002602001015190505f89600184612a6491906155d3565b601c8110612a7457612a74615b73565b602002015190505f612acf612a93612a8c858d6125ee565b60026125ee565b6108f28b612aa26001896155d3565b601c8110612ab257612ab2615b73565b60200201516108cf612ac9886108cf60018a612622565b87612622565b9050612af0816108cf610d49612aea876108cf600189612622565b86612609565b99508990508085612b026001876155d3565b81518110612b1257612b12615b73565b60200260200101818152505050505080612b2b90615bdb565b9050612a28565b509695505050505050565b5f61260382836125ee565b5f600181612b61612b5b87610100614ee8565b83612622565b905080612b815760405163835eb8f760e01b815260040160405180910390fd5b612b8961537c565b80518390525f5b7f0000000000000000000000000000000000000000000000000000000000000000811015612c72575f612bc48260096155bc565b612bcf906001615b39565b905084835f0151826101008110612be857612be8615b73565b60200201525f612bf9826001615b39565b90505b612c07600983615b39565b811015612c68578351612c4790612c1f6001846155d3565b6101008110612c3057612c30615b73565b60200201518a85601c8110610b7d57610b7d615b73565b8451826101008110612c5b57612c5b615b73565b6020020152600101612bfc565b5050600101612b90565b50608081018390525f602082018190525b610100811015612d8357612ca4612c9e83608001518a6125ee565b85612622565b8260a00151826101008110612cbb57612cbb615b73565b602002015260a0820151612ce590826101008110612cdb57612cdb615b73565b602002015161295d565b8260a00151826101008110612cfc57612cfc615b73565b602002018181525050612d4282602001516108d4845f0151846101008110612d2657612d26615b73565b60200201518560a00151856101008110610b7d57610b7d615b73565b60208301526080820151612d76907f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d66125ee565b6080830152600101612c83565b505f612d94836108cf61010061295d565b9050612da48260200151826125ee565b602083015260a0820151612dbf905f5b6020020151826125ee565b604083015260a0820151612deb90612dda60016101006155d3565b6101008110612db457612db4615b73565b60608301526040820151612e01908a6002610b7d565b60c08301819052612e61906108d4612e398b7f204bd3277422fad364751ad938e2b5e6a54cf8c68712848a692c553d0329f5d6612622565b60208d015160408e01516108cf91612e5091612622565b8e5160208901516108f291906125ee565b60c083018190526060830151612e9691612e8a916108d4906108cf8e600260200201518c612622565b6108f2858c6003610b7d565b60c08301819052159998505050505050505050565b612eb3615313565b5f6003612ee17f00000000000000000000000000000000000000000000000000000000000000006024615b39565b612eeb9190615b39565b612ef6906003615b39565b90505f5b81811015612f2c57612f24858281518110612f1757612f17615b73565b6020026020010151613154565b600101612efa565b50604051600190815b60018401811015612f915760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612f35565b5080518452602081015160208501525080612fbf576040516352ec174560e11b815260040160405180910390fd5b505092915050565b612fcf615313565b5f516020615c6e5f395f51905f5282602001515f516020615c6e5f395f51905f52612ffa91906155d3565b6130049190615bbc565b60208301525090565b5f5f5f61301986613093565b915091506130256153c0565b82518152602080840151818301528251604080840191909152838201516060840152875160808401528782015160a0840152865160c08401528682015160e084015251610bbd9161307891849101615bf0565b6040516020818303038152906040528051906020012061264a565b61309b615313565b6130a3615313565b82516020808501516040860151606087015160cc90811b608892831b604494851b90961795909517949094178652608087015160a088015160c089015160e08a0151871b90841b91851b9092171717868401526101008701516101208801516101408901516101608a0151871b90841b91851b909217171785526101808701516101a08801516101c08901516101e09099015190951b9790911b9390911b1791909117939093179281019290925291565b805160208201515f5f516020615c6e5f395f51905f528380095f516020615c6e5f395f51905f5260035f516020615c6e5f395f51905f52838709085f516020615c6e5f395f51905f5284850914915050806131ed5760405162461bcd60e51b8152602060048201526019602482015278706f696e74206973206e6f74206f6e2074686520637572766560381b60448201526064016100e5565b50505050565b6131fb615313565b613203615313565b61320d8386614f49565b90506132198185614f9f565b95945050505050565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e556101808201525f9081906101a00160405160208183030381529060405290505f5f60086001600160a01b0316836040516133b89190615c24565b5f60405180830381855afa9150503d805f81146133f0576040519150601f19603f3d011682016040523d82523d5f602084013e6133f5565b606091505b50915091508180156128115750808060200190518101906128119190615c3a565b5f613422846007615000565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f80000005f61348361347d613457856003612622565b6108cf6134726134678b5f615000565b6108cf8c601d615000565b6108cf8b601c615000565b836125ee565b90506135046134f96134e06134c76134ae856108d46134a38d6002615000565b6108cf8e601c615000565b6108d46134bc8c6003615000565b6108cf8d601d615000565b6108d46134d58b6004615000565b6108cf8c601e615000565b6108d46134ee8a6005615000565b6108cf8b601f615000565b6108d4886001615000565b9050613523816108d4613518866001612622565b6108cf8a6027615000565b905061352f81846125ee565b905061353b81856125ee565b8552505f905061357561356b61356061355588601c615000565b6108d489601f615000565b6108f2886024615000565b6108d4875f615000565b9050613586816108cf846002612622565b9050613597816108cf846001612622565b90506135a381836125ee565b90506135af81846125ee565b9050808460015b60200201525050505050565b5f5f5f6135f86135ee6135d689601c615000565b6108d46135e48b6012615000565b8a606001516125ee565b8760800151612609565b9050613631816108cf61362761360f8b601d615000565b6108d461361d8d6013615000565b8c606001516125ee565b8960800151612609565b9050613656816108cf6136276136488b601e615000565b6108d461361d8d6014615000565b905061367b816108cf61362761366d8b601f615000565b6108d461361d8d6015615000565b92505f905061369f6135ee61369189601c615000565b6108d46135e48b600e615000565b90506136c4816108cf6136276136b68b601d615000565b6108d461361d8d600f615000565b90506136e9816108cf6136276136db8b601e615000565b6108d461361d8d6010615000565b905061370e816108cf6136276137008b601f615000565b6108d461361d8d6011615000565b91505f905061373561372f613724896020615000565b6108d48a601a615000565b846125ee565b905061376a816108f261376461374c8b6028615000565b6108d461375a8d601b615000565b8c60a001516125ee565b856125ee565b905061377681856125ee565b6040860152505f61379961376461378e89601b615000565b6108cf8a6028615000565b9050808560035b602002015250505050505050565b5f5f61380c6137f46137dc6137c76136278a6016615000565b6108d46137d58b6017615000565b8a516125ee565b6108d46137ea8a6018615000565b89602001516125ee565b6108d4613802896019615000565b88604001516125ee565b91505f61384361382a61382089601c615000565b8860800151612609565b6108d46138388a6003615000565b6108cf8b6024615000565b90505f61386c61385489601d615000565b6108d46138618b5f615000565b6108cf8c6025615000565b90505f61389661387d8a601e615000565b6108d461388b8c6001615000565b6108cf8d6026615000565b90506138d56138bd6138af856108d4868d5f01516125ee565b6108d4848c602001516125ee565b6108d46138cb8c6004615000565b8b604001516125ee565b93505050505f6138e961372f886021615000565b90505f6138fa61372f896021615000565b90505f61393261391961390e8b6023615000565b6108d48c6006615000565b6108f26139278c6023615000565b6108cf8d6006615000565b90505f613950612b5b61394587896125ee565b6108cf8d6021615000565b905061395c81886125ee565b90505f6139846139766139708d6006615000565b876125ee565b6108f26139708e6022615000565b90505f6139928c6023615000565b90505f6139a2612b5b83846125ee565b60808c0185905260a08c0184905290506139bc818b6125ee565b8b6006602002015250505050505050505050505050565b5f6139df5f6001612622565b90505f6139ed5f6002612622565b90505f6139fb5f6003612622565b90505f613a17613a0c88601d615000565b6108f289601c615000565b90505f613a33613a2889601e615000565b6108f28a601d615000565b90505f613a4f613a448a601f615000565b6108f28b601e615000565b90505f613a6b613a608b6024615000565b6108f28c601f615000565b905083613a7c816108cf818b612609565b9050613a8c816108cf878a612609565b9050613a9c816108cf8789612609565b9050613aad816108cf8d6008615000565b9050613ab9818a6125ee565b60e08b01525082613ace816108cf818b612609565b9050613ade816108cf868a612609565b9050613aee816108cf8689612609565b9050613aff816108cf8d6008615000565b9050613b0b818a6125ee565b6101008b01525081613b21816108cf818b612609565b9050613b31816108cf858a612609565b9050613b41816108cf8589612609565b9050613b52816108cf8d6008615000565b9050613b5e818a6125ee565b6101208b01525080613b74816108cf818b612609565b9050613b84816108cf848a612609565b9050613b94816108cf8489612609565b9050613ba5816108cf8d6008615000565b9050613bb1818a6125ee565b610140909a019990995250505050505050505050565b613c006040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613c0b84601d615000565b8152613c1884601e615000565b6020820152613c28846024615000565b6040820152613c38846027615000565b6060820152613c48846026615000565b6080820152613c58846025615000565b60a08201525f613c69856002615000565b90505f613c76865f615000565b90505f613c8a8460400151855f0151612622565b90505f613c9f856020015186602001516125ee565b606086015190915086905f90613cb590806125ee565b90505f613cd3613ccd89602001518a606001516125ee565b886125ee565b90505f613cf2613ceb8a60a001518b60400151612609565b8a51612609565b9050613d0161397082886125ee565b9050613d28613d22613d1c613d168487612622565b88612622565b84612609565b83612609565b9050613d50613d45613d3a83876125ee565b6108cf8f6009615000565b6108cf60018a612622565b6101608c015250505050602085015160808601515f91613d6f91612609565b90505f613d8d613d838860600151886125ee565b8860200151612622565b90505f613db1613d9d84876125ee565b6108d46137648b60a001518c5f0151612622565b9050613dd9613dce613dc3838c6125ee565b6108cf8e6009615000565b6108cf600189612622565b6101808b0152505f9150613dfa9050613df3836011612609565b87516125ee565b90505f613e078384612609565b9050613e138182612609565b90505f613e218360096125ee565b9050613e4a613e4461372f613e3d8b60a001518c5f0151612609565b8b51612609565b82612622565b60c089018190525f90613e6590613ccd90613d3a908d6125ee565b9050613e788b600b602002015182612609565b6101608c0152505086515f9250613e9f9150613df390613e989080612609565b8851612609565b90505f613edf613eba836108cf8a5f01518b60a00151612622565b60208901516108f290613ecd9080612609565b6108cf8b602001518c60800151612609565b9050613efc89600c60200201516108d4613ccd613d3a858d6125ee565b89600c602002015250505050505050505050565b613f7a604051806101e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b613f92613f8886601e615000565b85604001516125ee565b808252613fb1906108d4613fa788601d615000565b87602001516125ee565b808252613fc6906108d4613df388601c615000565b808252613fd8906108d4876001615000565b80825260208201819052613ff1906108f287601f615000565b815261400c614001866024615000565b6108f287601c615000565b608082015261402a61401f866027615000565b6108f287601f615000565b60608201526080810151614043906108cf816001612622565b6101c082015260808101516140839061407990614072906108cf60015f516020615c8e5f395f51905f526155d3565b6001612609565b82606001516125ee565b60a082018190526140b9906140ab906108cf6140a0896002615000565b6108cf8a6003615000565b6108cf61376488600a615000565b83600e60200201526101c08101516140dd906140ab906108cf6140a0896002615000565b6101e08401528051614102906108cf6140f7886002615000565b6108cf896003615000565b6101208201525f61412161411787601f615000565b8360200151612622565b9050614132816108cf836001612622565b60e083015261414f614145876026615000565b86604001516125ee565b60408301819052614172906108d4614168896025615000565b88602001516125ee565b60408301819052614192906108d461418b896024615000565b88516125ee565b60408301526141af6141a5876027615000565b8360400151612622565b60408301525f6141ce6141c3886026615000565b6108f289601e615000565b90506142206141fb61347d614072866080015160015f516020615c8e5f395f51905f526108cf91906155d3565b6108cf614072866040015160015f516020615c8e5f395f51905f526108cf91906155d3565b60c084015260408301516142429061423890806125ee565b8460400151612622565b61010084015260c083015161426e90614260906108cf8a6004615000565b6108cf6139708a600a615000565b6102008601526101c083015161428d90614260906108cf8a6004615000565b6102208601526101008301516142ac90614260906108cf8a6004615000565b61024086015260e08301516142c6906108cf896004615000565b6101408401526142e56142da886025615000565b6108f289601d615000565b6101608401526080830151614323906141c39061431890614072906108cf60015f516020615c8e5f395f51905f526155d3565b8561016001516125ee565b61018084018190526101208401516101a0850181905261435a916108d4906108cf61434f8c6005615000565b6108cf8d6002615000565b6101a08401819052835161437a91906108d4906108cf61434f8c5f615000565b6101a084018190526101408401516143929190612609565b6101a084018190526143ac906108cf6139708a600a615000565b6101a0840181905285600d6137a0565b6143f56040518060e001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61442a61441161440686601c615000565b6108cf876025615000565b6108d461441f876024615000565b6108cf88601d615000565b815261446f61446461444b61444087601c615000565b6108cf88601f615000565b6108d461445988601d615000565b6108cf89601e615000565b6108f2866026615000565b6040820181905261448490600160441b6125ee565b6040820181905261449a906108f2866027615000565b6040820181905281516144ad9190612609565b604082018190526144c3906108cf866005615000565b604082015280516144d890600160441b6125ee565b8082526144f8906108d46144ed876024615000565b6108cf886025615000565b8082526020820181905261451f906108f261451487601e615000565b6108d488601f615000565b60208201819052614535906108cf866004615000565b6020820152805160608201819052614552906108d486601f615000565b60608201819052614576906108f261456b876026615000565b6108d4886027615000565b6060820181905261458b906108cf865f615000565b8160600181815250505f6145b46145aa83602001518460400151612609565b8360600151612609565b90506145c5816108cf876003615000565b90506145dd6145d5866025615000565b6140006125ee565b608083018190526145f3906108d4876024615000565b60808301819052614606906140006125ee565b6080830181905261461c906108d487601e615000565b6080830181905261462f906140006125ee565b60808301819052614645906108d487601d615000565b60808301819052614658906140006125ee565b6080830181905261466e906108d487601c615000565b60808301819052614684906108f287601f615000565b6080830181905261469a906108cf876005615000565b60808301526146ad6145d5866026615000565b60a083018190526146c3906108d4876025615000565b60a083018190526146d6906140006125ee565b60a083018190526146ec906108d4876024615000565b60a083018190526146ff906140006125ee565b60a08301819052614715906108d487601f615000565b60a08301819052614728906140006125ee565b60a0830181905261473e906108d487601e615000565b60a08301819052614754906108f2876027615000565b60a08301819052614769906108cf875f615000565b60a0830181905260808301515f916147819190612609565b9050614792816108cf886004615000565b905061479e8282612609565b60c084018190526147b7906108cf61397089600b615000565b60c084018190528560136020020152505050505050565b6148446040518061022001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b61485d61485285601c615000565b6108d4866002615000565b815261487861486d85601d615000565b6108d4866003615000565b602082015261489661488b85601e615000565b6108d4866004615000565b60408201526148b46148a985601f615000565b6108d4866005615000565b606082015280516148e6906148df906148d8906148d190806125ee565b84516125ee565b83516125ee565b82516125ee565b608082015260208101516149249061491a906149109061490690806125ee565b84602001516125ee565b83602001516125ee565b82602001516125ee565b60a08201526040810151614962906149589061494e9061494490806125ee565b84604001516125ee565b83604001516125ee565b82604001516125ee565b60c08201526060810151614996906140799061498c9061498290806125ee565b84606001516125ee565b83606001516125ee565b60e0820152608081015160a08201516149af9190612609565b61010082015260c081015160e08201516149c99190612609565b61012082015260a08101516149ed906149e29080612609565b826101200151612609565b61014082015260e0810151614a1190614a069080612609565b826101000151612609565b610160820152610120810151614a279080612609565b6101e08201819052614a4890614a3d9080612609565b826101600151612609565b6101e0820152610100810151614a5e9080612609565b6101a08201819052614a7f90614a749080612609565b826101400151612609565b6101a08201819052610160820151614a9691612609565b6101808201526101408101516101e0820151614ab29190612609565b6101c0820152614ac661347d85600c615000565b6102008201819052610280840151610180830151614af1926108d4916108cf906108f28a6024615000565b8360146020020152614b2183601560200201516108d48361020001516108cf856101a001516108f28a6025615000565b8360156020020152614b5183601660200201516108d48361020001516108cf856101c001516108f28a6026615000565b8360166020020152614b8183601760200201516108d48361020001516108cf856101e001516108f28a6027615000565b836017602002015250505050565b614be16040518061016001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040518060800160405280614c167f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e76125d6565b8152602001614c447f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b6125d6565b8152602001614c717e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac156125d6565b8152602001614c9f7f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b6125d6565b90529050614cbc614cb186601c615000565b6108d4876002615000565b6101208301819052614cfb90614cf090614ce590614cda90806125ee565b8561012001516125ee565b8461012001516125ee565b8361012001516125ee565b8252614d0885601d615000565b6020830152614d1885601e615000565b6040830152614d2885601f615000565b606083015281516020830151614d50916145aa91614d469190612609565b8460400151612609565b6080830152614d6361372f86600d615000565b6101408301528151614d8490614d7a90835f610b7d565b8360800151612609565b60a0830152614db084601860200201516108d48461014001516108cf8660a001516108f28b6024615000565b6103008501526020820151614dcb90614d7a90836001610b7d565b60c0830152614df784601960200201516108d48461014001516108cf8660c001516108f28b6025615000565b6103208501526040820151614e1290614d7a90836002610b7d565b60e0830152614e3e84601a60200201516108d48461014001516108cf8660e001516108f28b6026615000565b6103408501526060820151614e5990614d7a90836003610b7d565b610100830152614e8784601b60200201516108d48461014001516108cf8661010001516108f28b6027615000565b84601b6135b6565b815160015b601c811015614ee157614ed7826108d48684601c8110614eb657614eb6615b73565b602002015186614ec76001876155d3565b601b8110610b7d57610b7d615b73565b9150600101614e94565b5092915050565b5f5f8390505f60405160208152602080820152602060408201528260608201528460808201525f516020615c8e5f395f51905f5260a082015260205f60c08360055afa80614f34575f5ffd5b505f5160809190910160405295945050505050565b614f51615313565b614f59615313565b604051835181526020840151602082015284604082015260408160608360075afa80614f83575f5ffd5b5080518252602080820151908301526060016040529392505050565b614fa7615313565b614faf615313565b6040518451815260208501516020820152835160408201526020840151606082015260408160808360065afa80614fe4575f5ffd5b5080518252602080820151908301526080016040529392505050565b5f8282602881111561501457615014615c59565b6029811061502457615024615b73565b60200201519392505050565b604051806103e001604052805f81526020015f81526020015f8152602001615056615313565b8152602001615063615313565b8152602001615070615313565b815260200161507d615313565b815260200161508a615313565b8152602001615097615313565b81526020016150a4615313565b81526020016150b1615313565b81526020016150be615313565b81526020016150cb615313565b81526020016150d8615313565b81526020016150e5615313565b81526020016150f2615313565b81526020016150ff615313565b815260200161510c615313565b8152602001615119615313565b8152602001615126615313565b8152602001615133615313565b8152602001615140615313565b815260200161514d615313565b815260200161515a615313565b8152602001615167615313565b8152602001615174615313565b8152602001615181615313565b815260200161518e615313565b815260200161519b615313565b81526020016151a8615313565b81526020016151b5615313565b905290565b604051806102a001604052806151ce6153df565b81526020016151db615313565b81526020016151e8615313565b81526020016151f5615313565b8152602001615202615313565b815260200161520f615313565b815260200161521c615313565b8152602001615229615313565b8152602001615236615313565b81526020016152436153fe565b81526020015f815260200161525661542b565b8152602001615263615459565b81526020015f8152602001615276615313565b81526020015f8152602001615289615478565b815260200161529661535d565b815260200161519b6154a6565b604051806101c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020016152e16154a6565b81526020016152ee6154a6565b81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052806151a8615313565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518060e0016040528061538f6154c4565b81526020015f81526020015f81526020015f81526020015f81526020016153b46154c4565b81526020015f81525090565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180606001604052806003905b615415615313565b81526020019060019003908161540d5790505090565b604051806103800160405280601c905b61544361533e565b81526020019060019003908161543b5790505090565b6040518061052001604052806029906020820280368337509192915050565b604051806103600160405280601b905b615490615313565b8152602001906001900390816154885790505090565b60405180608001604052806004906020820280368337509192915050565b604051806120000160405280610100906020820280368337509192915050565b5f5f5f5f604085870312156154f7575f5ffd5b84356001600160401b0381111561550c575f5ffd5b8501601f8101871361551c575f5ffd5b80356001600160401b03811115615531575f5ffd5b876020828401011115615542575f5ffd5b6020918201955093508501356001600160401b03811115615561575f5ffd5b8501601f81018713615571575f5ffd5b80356001600160401b03811115615586575f5ffd5b8760208260051b840101111561559a575f5ffd5b949793965060200194505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417612603576126036155a8565b81810381811115612603576126036155a8565b805f5b60108110156131ed5781518452602093840193909101906001016155e9565b805f5b60038110156131ed5761562984835180518252602090810151910152565b604093909301926020919091019060010161560b565b805f5b601c8110156131ed578151845f5b600981101561566f578251825260209283019290910190600101615650565b505050610120939093019260209190910190600101615642565b805f5b60298110156131ed57815184526020938401939091019060010161568c565b805f5b601b8110156131ed576156cc84835180518252602090810151910152565b60409390930192602091909101906001016156ae565b805f5b601c8110156131ed5781518452602093840193909101906001016156e5565b805f5b60048110156131ed578151845260209384019390910190600101615707565b8183525f6001600160fb1b0383111561573d575f5ffd5b8260051b80836020870137939093016020019392505050565b6157618188516155e6565b5f602088015161577f61020084018280518252602090810151910152565b5060408801518051610240840152602090810151610260840152606089015180516102808501528101516102a0840152608089015180516102c08501528101516102e084015260a0890151805161030085015281015161032084015260c0890151805161034085015281015161036084015260e089015180516103808501528101516103a084015261010089015180516103c085015201516103e0830152610120880151615831610400840182615608565b506101408801516104c08301526101608801516158526104e084018261563f565b50610180880151615867612460840182615689565b506101a08801516129808301526101c088015180516129a0840152602001516129c08301526101e08801516129e08301526102008801516158ac612a008401826156ab565b506102208801516158c16130c08401826156e2565b506102408801516158d6613440840182615704565b5061026088015180516134c08401526020908101516134e0840152610280890151805161350085015201516135208301526135c0613540830181905261591f9083018789615726565b613560830195909552506135808101929092526135a0909101529392505050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b038111828210171561597757615977615940565b60405290565b604051601f8201601f191681016001600160401b03811182821017156159a5576159a5615940565b604052919050565b5f60c082840312156159bd575f5ffd5b60405160c081016001600160401b03811182821017156159df576159df615940565b604090815283518252602080850151908301528381015190820152606080840151908201526080808401519082015260a0928301519281019290925250919050565b5f82601f830112615a30575f5ffd5b5f610360615a3d8161597d565b915083018185821115615a4e575f5ffd5b845b82811015615a68578051825260209182019101615a50565b509195945050505050565b5f82601f830112615a82575f5ffd5b5f610380615a3d8161597d565b5f610be0828403128015615aa1575f5ffd5b50615aaa615954565b615ab484846159ad565b8152615ac38460c08501615a21565b6020820152615ad6846104208501615a73565b60408201526107a08301516060820152615af4846107c08501615a73565b6080820152610b4083015160a0820152610b6083015160c0820152610b8083015160e0820152610ba0830151610100820152610bc09092015161012083015250919050565b80820180821115612603576126036155a8565b5f5f85851115615b5a575f5ffd5b83861115615b66575f5ffd5b5050820193919092039150565b634e487b7160e01b5f52603260045260245ffd5b5f60018201615b9857615b986155a8565b5060010190565b80356020831015612603575f19602084900360031b1b1692915050565b5f82615bd657634e487b7160e01b5f52601260045260245ffd5b500690565b5f81615be957615be96155a8565b505f190190565b5f8183825b6008811015615c14578151835260209283019290910190600101615bf5565b5050506101008201905092915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615c4a575f5ffd5b815180151581146103dd575f5ffd5b634e487b7160e01b5f52602160045260245ffdfe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212209efbf9208fe279f511b6e73b6960090caad6087488a190f0c502bf401cff237864736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":11,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"withdrawVerifier#WithdrawVerifier","networkInteractionId":1,"nonce":11,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40528000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x04844ebb991b59cc137978113e5c12571153a799d8b6a50bd6fcf06bc5a39f0a"},"type":"TRANSACTION_SEND"} +{"futureId":"depositVerifier#DepositVerifier","hash":"0x8ce008102da62a7c9582b12bf67a9b1eccde28ec2a20df5ad89736de89c5c04f","networkInteractionId":1,"receipt":{"blockHash":"0x78d34b5a8ca8c304e07ff2c7887f61147785f3397b7f022a922ce8d1a5bbddd9","blockNumber":233653906,"contractAddress":"0xd3090af4727886D9b51FA38AC001025796Dd5E14","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"depositVerifier#DepositVerifier","result":{"address":"0xd3090af4727886D9b51FA38AC001025796Dd5E14","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","hash":"0xa09b04e22f35f94e7ec3bbab24772cf75f7c3c602d56979da9334c988934fe10","networkInteractionId":1,"receipt":{"blockHash":"0x4498e3981f079371c401468865a10f96977fcd1f3cd903e497feb7e1c71b4f3f","blockNumber":233653914,"contractAddress":"0x287243bD7650643B691cED24dfE854964Df045A1","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferExternalVerifier#TransferExternalVerifier","result":{"address":"0x287243bD7650643B691cED24dfE854964Df045A1","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"transferVerifier#TransferVerifier","hash":"0xf227357736e685850eb46a38f977bb127fd0ebd7af9a6cd2242459ba42d2daa5","networkInteractionId":1,"receipt":{"blockHash":"0x7512bd50ca3e005173a544f3d7e5eb8090677e8fc0bd175169cf65475ca6ff82","blockNumber":233653922,"contractAddress":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"transferVerifier#TransferVerifier","result":{"address":"0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"futureId":"withdrawVerifier#WithdrawVerifier","hash":"0x04844ebb991b59cc137978113e5c12571153a799d8b6a50bd6fcf06bc5a39f0a","networkInteractionId":1,"receipt":{"blockHash":"0x3cee1defc7232cfb8ce686fc1d108effd91e133ffc7d49d2529b2f793453bed2","blockNumber":233653930,"contractAddress":"0x8a6753C2fFb09Ab4d64763a8C5Ef4b31aF5f9Eb2","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"withdrawVerifier#WithdrawVerifier","result":{"address":"0x8a6753C2fFb09Ab4d64763a8C5Ef4b31aF5f9Eb2","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} +{"artifactId":"commbankDotEth#CommBankDotEth","constructorArgs":["0xd3090af4727886D9b51FA38AC001025796Dd5E14","0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e","0x8a6753C2fFb09Ab4d64763a8C5Ef4b31aF5f9Eb2","0x287243bD7650643B691cED24dfE854964Df045A1"],"contractName":"CommBankDotEth","dependencies":["depositVerifier#DepositVerifier","transferVerifier#TransferVerifier","withdrawVerifier#WithdrawVerifier","transferExternalVerifier#TransferExternalVerifier"],"from":"0xd55b4fe4795c117603b3b41fe1d39c5e4235478a","futureId":"commbankDotEth#CommBankDotEth","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteraction":{"data":"0x60c06040526002805463ffffffff191690555f6003557f2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384600d5573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60a05234801561005c575f5ffd5b50604051612b38380380612b3883398101604081905261007b91610225565b600c608081905261008d60018261028a565b610098906002610380565b600455505f80805260016020527f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f7fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb495560068054336001600160a01b031991821681179092556008805482166001600160a01b0389811691909117909155600980548316888316179055600a80548316878316179055600b8054909216908516179055610145919061015d565b50600d54610153903361015d565b5050505050610392565b5f8281526007602090815260408083206001600160a01b038516845290915281205460ff16610201575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff191660011790556101b93390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610204565b505f5b92915050565b80516001600160a01b0381168114610220575f5ffd5b919050565b5f5f5f5f60808587031215610238575f5ffd5b6102418561020a565b935061024f6020860161020a565b925061025d6040860161020a565b915061026b6060860161020a565b905092959194509250565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561020457610204610276565b6001815b60018411156102d8578085048111156102bc576102bc610276565b60018416156102ca57908102905b60019390931c9280026102a1565b935093915050565b5f826102ee57506001610204565b816102fa57505f610204565b8160018114610310576002811461031a57610336565b6001915050610204565b60ff84111561032b5761032b610276565b50506001821b610204565b5060208310610133831016604e8410600b8410161715610359575081810a610204565b6103655f19848461029d565b805f190482111561037857610378610276565b029392505050565b5f61038b83836102e0565b9392505050565b60805160a0516127696103cf5f395f81816104c901528181610b58015281816116b5015261199601525f818161023e0152611ef501526127695ff3fe6080604052600436106101b4575f3560e01c806390eeb02b116100ea578063c2b40ae41161008e578063c2b40ae41461055c578063c46165b514610587578063c51636df1461059a578063cd87a3b4146105b9578063d547741f146105cd578063d5f39488146105ec578063e82955881461060b578063f178e47c1461062a578063fc7e9c6f14610655575f5ffd5b806390eeb02b1461043657806391d1485414610467578063a217fddf14610486578063a6232a9314610499578063a734f06e146104b8578063aa77c44a146104eb578063b42147cd1461050a578063bc72436f1461053d575f5ffd5b806336568abe1161015c57806336568abe1461031a5780635bb93995146103395780635e125d0d1461035857806367843a5b146103775780637ecf686d1461039657806380fc7498146103c457806384746900146103d9578063864eb164146103f85780638daed52814610417575f5ffd5b806217cd8b146101b857806301ffc9a7146101fe5780630ef267431461022d5780631a702a2414610260578063248a9ca31461029757806326120c88146102c55780632f2ff15d146102e4578063353efdcf14610305575b5f5ffd5b3480156101c3575f5ffd5b506101eb7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6040519081526020015b60405180910390f35b348015610209575f5ffd5b5061021d6102183660046120ab565b61066a565b60405190151581526020016101f5565b348015610238575f5ffd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026b575f5ffd5b5060055461027f906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b3480156102a2575f5ffd5b506101eb6102b13660046120d9565b5f9081526007602052604090206001015490565b3480156102d0575f5ffd5b5060085461027f906001600160a01b031681565b3480156102ef575f5ffd5b506103036102fe366004612106565b6106a0565b005b348015610310575f5ffd5b506101eb600d5481565b348015610325575f5ffd5b50610303610334366004612106565b6106ca565b348015610344575f5ffd5b506101eb610353366004612130565b610702565b348015610363575f5ffd5b50610303610372366004612150565b6107fa565b348015610382575f5ffd5b506103036103913660046121ed565b6108c5565b3480156103a1575f5ffd5b5061021d6103b03660046120d9565b600c6020525f908152604090205460ff1681565b3480156103cf575f5ffd5b506101eb60045481565b3480156103e4575f5ffd5b506103036103f3366004612257565b610ccf565b348015610403575f5ffd5b50600a5461027f906001600160a01b031681565b348015610422575f5ffd5b5060095461027f906001600160a01b031681565b348015610441575f5ffd5b506002546104529063ffffffff1681565b60405163ffffffff90911681526020016101f5565b348015610472575f5ffd5b5061021d610481366004612106565b610fdf565b348015610491575f5ffd5b506101eb5f81565b3480156104a4575f5ffd5b5061021d6104b33660046120d9565b611009565b3480156104c3575f5ffd5b5061027f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f6575f5ffd5b506103036105053660046122f3565b611082565b348015610515575f5ffd5b506101eb7f124005ad54174bbcb8c2dd053ea318daa80106cdcc518731504b771d6006123f81565b348015610548575f5ffd5b50610303610557366004612257565b61138b565b348015610567575f5ffd5b506101eb6105763660046120d9565b60016020525f908152604090205481565b610303610595366004612257565b6118ce565b3480156105a5575f5ffd5b50600b5461027f906001600160a01b031681565b3480156105c4575f5ffd5b50610452606481565b3480156105d8575f5ffd5b506103036105e7366004612106565b611b21565b3480156105f7575f5ffd5b5060065461027f906001600160a01b031681565b348015610616575f5ffd5b506101eb6106253660046120d9565b611b45565b348015610635575f5ffd5b506101eb6106443660046120d9565b5f6020819052908152604090205481565b348015610660575f5ffd5b506101eb60035481565b5f6001600160e01b03198216637965db0b60e01b148061069a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f828152600760205260409020600101546106ba81611d8d565b6106c48383611d9a565b50505050565b6001600160a01b03811633146106f35760405163334bd91960e11b815260040160405180910390fd5b6106fd8282611e2b565b505050565b5f5f8383604051602001610720929190918252602082015260400190565b60408051601f19818403018152908290526005549092505f9182916001600160a01b0316906107509085906123a8565b5f60405180830381855afa9150503d805f8114610788576040519150601f19603f3d011682016040523d82523d5f602084013e61078d565b606091505b5091509150816107dc5760405162461bcd60e51b8152602060048201526015602482015274141bdcd95a591bdb8c881a185cda0819985a5b1959605a1b60448201526064015b60405180910390fd5b808060200190518101906107f091906123be565b9695505050505050565b6005546001600160a01b0316156108495760405162461bcd60e51b815260206004820152601360248201527243616e2774207365742069742074776963652160681b60448201526064016107d3565b6006546001600160a01b031633146108a35760405162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206465706c6f7965722063616e2073657420706f736569646f6e000060448201526064016107d3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6108e882825f8181106108da576108da6123d5565b905060200201355f1c611009565b6109045760405162461bcd60e51b81526004016107d3906123e9565b600a54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e49061093a908890889088908890600401612438565b6020604051808303815f875af1158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190612482565b9050806109c25760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b60448201526064016107d3565b60015b60038111610ac0575f8484838181106109e0576109e06123d5565b9050602002013514610aae57600c5f858584818110610a0157610a016123d5565b602090810292909201358352508101919091526040015f205460ff1615610a3a5760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f868685818110610a5157610a516123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550838382818110610a8d57610a8d6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80610ab8816124e6565b9150506109c5565b505f5b6003811015610cc7575f610ad88260046124fe565b90505f610ae68360076124fe565b90505f610af484600a6124fe565b90505f878785818110610b0957610b096123d5565b905060200201355f1c90505f888885818110610b2757610b276123d5565b905060200201355f1c90505f898985818110610b4557610b456123d5565b60200291909101359150508115610cb5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603610c245781471015610baf5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114610bf8576040519150601f19603f3d011682016040523d82523d5f602084013e610bfd565b606091505b5050905080610c1e5760405162461bcd60e51b81526004016107d390612543565b50610cb5565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb90610c549085908790600401612570565b6020604051808303815f875af1158015610c70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190612482565b905080610cb35760405162461bcd60e51b81526004016107d390612589565b505b505060019094019350610ac392505050565b505050505050565b610ce484845f8181106108da576108da6123d5565b610d005760405162461bcd60e51b81526004016107d3906123e9565b600954604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490610d36908a908a908a908a90600401612438565b6020604051808303815f875af1158015610d52573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d769190612482565b905080610dbe5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103a3930b739b332b910383937b7b360511b60448201526064016107d3565b60015b610dcd600360016124fe565b811015610ebd575f868683818110610de757610de76123d5565b9050602002013514610eb557600c5f878784818110610e0857610e086123d5565b602090810292909201358352508101919091526040015f205460ff1615610e415760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110610e5857610e586123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff021916908315150217905550858582818110610e9457610e946123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b600101610dc1565b505f610ecb600360016124fe565b90505b6003610edb8160016124fe565b610ee591906124fe565b811015610f38575f868683818110610eff57610eff6123d5565b9050602002013514610f3057610f2e868683818110610f2057610f206123d5565b905060200201355f1c611e96565b505b600101610ece565b505f5b600381108015610f4a57508281105b15610fd557838382818110610f6157610f616123d5565b9050602002810190610f7391906125b8565b159050610fc3575f5160206127145f395f51905f52848483818110610f9a57610f9a6123d5565b9050602002810190610fac91906125b8565b604051610fba9291906125fa565b60405180910390a15b80610fcd816124e6565b915050610f3b565b5050505050505050565b5f9182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f815f0361101857505f919050565b60025463ffffffff16805b63ffffffff81165f908152600160205260409020548403611048575060019392505050565b8063ffffffff165f03611059575060645b8061106381612615565b9150508163ffffffff168163ffffffff160361102357505f9392505050565b600d5461108e81611d8d565b6040516323b872dd60e01b8152336004820152306024820152604481018990525f906001600160a01b038b16906323b872dd906064016020604051808303815f875af11580156110e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111049190612482565b9050806111535760405162461bcd60e51b815260206004820152601a60248201527f6661696c656420746f207472616e73666572206465706f73697400000000000060448201526064016107d3565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611189908c908c908c908c90600401612438565b6020604051808303815f875af11580156111a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c99190612482565b9050806111e85760405162461bcd60e51b81526004016107d390612633565b868660018181106111fb576111fb6123d5565b905060200201355f1c6001600160a01b03168b6001600160a01b03161461125d5760405162461bcd60e51b815260206004820152601660248201527508aa486646040c2c8c8e4cae6e640dad2e6dac2e8c6d60531b60448201526064016107d3565b86866002818110611270576112706123d5565b905060200201355f1c6001600160401b03168a146112cb5760405162461bcd60e51b81526020600482015260186024820152771059191c995cdcc8185b5bdd5b9d081a5b98dbdc9c9958dd60421b60448201526064016107d3565b6112e087875f818110610f2057610f206123d5565b505f5b6003811080156112f257508481105b1561137d57858582818110611309576113096123d5565b905060200281019061131b91906125b8565b15905061136b575f5160206127145f395f51905f52868683818110611342576113426123d5565b905060200281019061135491906125b8565b6040516113629291906125fa565b60405180910390a15b80611375816124e6565b9150506112e3565b505050505050505050505050565b6113a084845f8181106108da576108da6123d5565b6113bc5760405162461bcd60e51b81526004016107d3906123e9565b600b54604051633a94343960e21b81525f916001600160a01b03169063ea50d0e4906113f2908a908a908a908a90600401612438565b6020604051808303815f875af115801561140e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190612482565b9050806114815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207472616e736665722065787465726e616c2070726f6f660060448201526064016107d3565b60015b6003811161157f575f86868381811061149f5761149f6123d5565b905060200201351461156d57600c5f8787848181106114c0576114c06123d5565b602090810292909201358352508101919091526040015f205460ff16156114f95760405162461bcd60e51b81526004016107d3906124a1565b6001600c5f888885818110611510576115106123d5565b9050602002013581526020019081526020015f205f6101000a81548160ff02191690831515021790555085858281811061154c5761154c6123d5565b905060200201355f5160206126f45f395f51905f5260405160405180910390a25b80611577816124e6565b915050611484565b505f61158d600360016124fe565b90505b600361159d8160016124fe565b6115a791906124fe565b8110156115ec575f8686838181106115c1576115c16123d5565b90506020020135146115e4576115e2868683818110610f2057610f206123d5565b505b600101611590565b5060075f6115fb6003836124fe565b90505f6116096003836124fe565b90505f5b6003811015611824575f61162182866124fe565b90505f61162e83866124fe565b90505f61163b84866124fe565b90505f8c8c85818110611650576116506123d5565b905060200201355f1c90505f8d8d8581811061166e5761166e6123d5565b905060200201355f1c90505f8e8e8581811061168c5761168c6123d5565b905060200201355f1c90505f821180156116ae57506001600160a01b03811615155b15611812577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611781578147101561170c5760405162461bcd60e51b81526004016107d390612511565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611755576040519150601f19603f3d011682016040523d82523d5f602084013e61175a565b606091505b505090508061177b5760405162461bcd60e51b81526004016107d390612543565b50611812565b60405163a9059cbb60e01b81525f906001600160a01b0385169063a9059cbb906117b19085908790600401612570565b6020604051808303815f875af11580156117cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f19190612482565b9050806118105760405162461bcd60e51b81526004016107d390612589565b505b50506001909401935061160d92505050565b505f5b60038110801561183657508581105b156118c15786868281811061184d5761184d6123d5565b905060200281019061185f91906125b8565b1590506118af575f5160206127145f395f51905f52878783818110611886576118866123d5565b905060200281019061189891906125b8565b6040516118a69291906125fa565b60405180910390a15b806118b9816124e6565b915050611827565b5050505050505050505050565b600d546118da81611d8d565b600854604051633a94343960e21b81525f916001600160a01b03169063ea50d0e490611910908b908b908b908b90600401612438565b6020604051808303815f875af115801561192c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119509190612482565b90508061196f5760405162461bcd60e51b81526004016107d390612633565b85856001818110611982576119826123d5565b905060200201355f1c6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152601060248201526f082c8c8e4cae6e640dad2e6dac2e8c6d60831b60448201526064016107d3565b85856002818110611a1157611a116123d5565b905060200201355f1c6001600160401b03163414611a645760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081a5b98dbdc9c9958dd60821b60448201526064016107d3565b611a7986865f818110610f2057610f206123d5565b505f5b600381108015611a8b57508381105b15611b1657848482818110611aa257611aa26123d5565b9050602002810190611ab491906125b8565b159050611b04575f5160206127145f395f51905f52858583818110611adb57611adb6123d5565b9050602002810190611aed91906125b8565b604051611afb9291906125fa565b60405180910390a15b80611b0e816124e6565b915050611a7c565b505050505050505050565b5f82815260076020526040902060010154611b3b81611d8d565b6106c48383611e2b565b5f815f03611b7457507f1e2856f9f722631c878a92dc1d84283d04b76df3e1831492bdf7098c1e65e478919050565b81600103611ba357507f2c2eecb1b14035bfd9765e84195684b401a84fdb58c3c03f1bcea86dcf0c8105919050565b81600203611bd257507f237e412a71db31e5769f63d92346a09dd0f30b9c335e9d9aa96b6625eb537445919050565b81600303611c0157507f0b3ff120d61a7de2da3d80ff99d393796805c74be5c39e8a4c7436d1c65dad4c919050565b81600403611c3057507f0fc58e21665302678bef68714d9e5889583071f7bd3cf018b64fafc51b0a9cf3919050565b81600503611c5f57507f235df7c585524ed8a26aea20a0fb168038f10df71d84720c9a8c1b3e78e3b6cd919050565b81600603611c8e57507f1c6cabee394ea24dc09eab1788f7f62b367e95789f883e33690d94215d819264919050565b81600703611cbd57507f09bec327ab2c8dda5d2d435cd267cb21e71f21371a01739885817eb1625d8976919050565b81600803611cec57507f2d35519ad7061578be50cbbfe040327843f6b4cdf1458e01b5f9737dbaf82b18919050565b81600903611d1b57507f0f86c9e9c9e689394a4944bb87291a3f55cc930b21432fccf41b8267f1a98d6f919050565b81600a03611d4a57507f181c9ba70900093b180c96f55cc2b1d73d60b8ab613344cbba83b33cbcc94e2b919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b60448201526064016107d3565b919050565b611d97813361207c565b50565b5f611da58383610fdf565b611e24575f8381526007602090815260408083206001600160a01b03861684529091529020805460ff19166001179055611ddc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161069a565b505f61069a565b5f611e368383610fdf565b15611e24575f8381526007602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161069a565b6003546004545f91908103611ed95760405162461bcd60e51b8152602060048201526009602482015268151c995948119d5b1b60ba1b60448201526064016107d3565b5f818152602081905260408120849055819084905b611f1960017f0000000000000000000000000000000000000000000000000000000000000000612663565b811015611fe6575f611f2c60028561268a565b1590505f81611f4557611f40600186612663565b611f50565b611f508560016124fe565b602084811b82175f8181529182905260408220549293509190819003611f7c57611f7985611b45565b90505b8315611f9357611f8c8682610702565b9550611fa0565b611f9d8187610702565b95505b611fab60028861269d565b9650855f80611fc6611fbe8960016124fe565b60201b8b1790565b815260208101919091526040015f2055505060019092019150611eee9050565b506002545f906064906120009063ffffffff1660016126b0565b61200a91906126cc565b6002805463ffffffff191663ffffffff83169081179091555f9081526001602081905260409091208490559091506120439085906124fe565b600355604051869085907f9a40fd7d16dbc76bf1972bae17064a13dea280d9723bc57a2a89a516d45757f5905f90a35091949350505050565b6120868282610fdf565b6120a757808260405163e2517d3f60e01b81526004016107d3929190612570565b5050565b5f602082840312156120bb575f5ffd5b81356001600160e01b0319811681146120d2575f5ffd5b9392505050565b5f602082840312156120e9575f5ffd5b5035919050565b80356001600160a01b0381168114611d88575f5ffd5b5f5f60408385031215612117575f5ffd5b82359150612127602084016120f0565b90509250929050565b5f5f60408385031215612141575f5ffd5b50508035926020909101359150565b5f60208284031215612160575f5ffd5b6120d2826120f0565b5f5f83601f840112612179575f5ffd5b5081356001600160401b0381111561218f575f5ffd5b6020830191508360208285010111156121a6575f5ffd5b9250929050565b5f5f83601f8401126121bd575f5ffd5b5081356001600160401b038111156121d3575f5ffd5b6020830191508360208260051b85010111156121a6575f5ffd5b5f5f5f5f60408587031215612200575f5ffd5b84356001600160401b03811115612215575f5ffd5b61222187828801612169565b90955093505060208501356001600160401b0381111561223f575f5ffd5b61224b878288016121ad565b95989497509550505050565b5f5f5f5f5f5f6060878903121561226c575f5ffd5b86356001600160401b03811115612281575f5ffd5b61228d89828a01612169565b90975095505060208701356001600160401b038111156122ab575f5ffd5b6122b789828a016121ad565b90955093505060408701356001600160401b038111156122d5575f5ffd5b6122e189828a016121ad565b979a9699509497509295939492505050565b5f5f5f5f5f5f5f5f60a0898b03121561230a575f5ffd5b612313896120f0565b97506020890135965060408901356001600160401b03811115612334575f5ffd5b6123408b828c01612169565b90975095505060608901356001600160401b0381111561235e575f5ffd5b61236a8b828c016121ad565b90955093505060808901356001600160401b03811115612388575f5ffd5b6123948b828c016121ad565b999c989b5096995094979396929594505050565b5f82518060208501845e5f920191825250919050565b5f602082840312156123ce575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b6020808252600d908201526c496e76616c696420526f6f742160981b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f61244b604083018688612410565b82810360208401528381526001600160fb1b03841115612469575f5ffd5b8360051b80866020840137016020019695505050505050565b5f60208284031215612492575f5ffd5b815180151581146120d2575f5ffd5b602080825260179082015276139d5b1b1a599a595c88185b1c9958591e481cdc195b9d604a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f600182016124f7576124f76124d2565b5060010190565b8082018082111561069a5761069a6124d2565b602080825260189082015277496e73756666696369656e74204554482062616c616e636560401b604082015260600190565b602080825260139082015272115512081d1c985b9cd9995c8819985a5b1959606a1b604082015260600190565b6001600160a01b03929092168252602082015260400190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b5f5f8335601e198436030181126125cd575f5ffd5b8301803591506001600160401b038211156125e6575f5ffd5b6020019150368190038213156121a6575f5ffd5b602081525f61260d602083018486612410565b949350505050565b5f63ffffffff82168061262a5761262a6124d2565b5f190192915050565b602080825260169082015275496e76616c6964206465706f7369742070726f6f662160501b604082015260600190565b8181038181111561069a5761069a6124d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261269857612698612676565b500690565b5f826126ab576126ab612676565b500490565b63ffffffff818116838216019081111561069a5761069a6124d2565b5f63ffffffff8316806126e1576126e1612676565b8063ffffffff8416069150509291505056fe4aac17bcf1974f8ba294b28aaf75fe627cdcc9a03ac55bda3bfe158ab067383c1350ba861189904691f5a79791c8b0eb3c5ea51a8954ae413a167e05c66ca1e0a264697066735822122052479300eebe39dc664c535b8bf1f33e15975d115ef9240b8a7305cd8a7dcc2964736f6c634300081c0033000000000000000000000000d3090af4727886d9b51fa38ac001025796dd5e140000000000000000000000005eeaae6da50c2cbc94f8a0b25a1d9bad8225db1e0000000000000000000000008a6753c2ffb09ab4d64763a8c5ef4b31af5f9eb2000000000000000000000000287243bd7650643b691ced24dfe854964df045a1","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":12,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","networkInteractionId":1,"nonce":12,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"40000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0x9b9ea049428042ace650947aec3a7394b270ebfa4b21c91fe15f615c3fd4d008"},"type":"TRANSACTION_SEND"} +{"futureId":"commbankDotEth#CommBankDotEth","hash":"0x9b9ea049428042ace650947aec3a7394b270ebfa4b21c91fe15f615c3fd4d008","networkInteractionId":1,"receipt":{"blockHash":"0x682b8b1529b4e97e3fcea89c9b5f82ef8d805ee8a39389ab9f99671e4a0dfb0e","blockNumber":233653957,"contractAddress":"0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3","logs":[{"address":"0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3","data":"0x","logIndex":2,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]},{"address":"0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3","data":"0x","logIndex":3,"topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x2561bf26f818282a3be40719542054d2173eb0d38539e8a8d3cff22f29fd2384","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a","0x000000000000000000000000d55b4fe4795c117603b3b41fe1d39c5e4235478a"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"commbankDotEth#CommBankDotEth","result":{"address":"0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/contracts/ignition/modules/CommbankDotEth.ts b/contracts/ignition/modules/CommbankDotEth.ts index 4a7bee9..cb9fa56 100644 --- a/contracts/ignition/modules/CommbankDotEth.ts +++ b/contracts/ignition/modules/CommbankDotEth.ts @@ -4,18 +4,21 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import DepositVerifierModule from "./DepositVerifier"; import TransferVerifierModule from "./TransferVerifier"; import WithdrawVerifierModule from "./WithdrawVerifier"; +import TransferExternalVerifier from "./TransferExternalVerifier"; const CommbankDotEthModule = buildModule("commbankDotEth", (m) => { // Import the verifier modules const { depositVerifier } = m.useModule(DepositVerifierModule); const { transferVerifier } = m.useModule(TransferVerifierModule); const { withdrawVerifier } = m.useModule(WithdrawVerifierModule); + const { transferExternalVerifier } = m.useModule(TransferExternalVerifier); // Deploy CommBankDotEth with the verifier contracts (not libraries) const commbankDotEth = m.contract("CommBankDotEth", [ depositVerifier, transferVerifier, withdrawVerifier, + transferExternalVerifier, ]); return { @@ -23,6 +26,7 @@ const CommbankDotEthModule = buildModule("commbankDotEth", (m) => { depositVerifier, transferVerifier, withdrawVerifier, + transferExternalVerifier, }; }); diff --git a/contracts/ignition/modules/TransferExternalVerifier.ts b/contracts/ignition/modules/TransferExternalVerifier.ts new file mode 100644 index 0000000..74e03cc --- /dev/null +++ b/contracts/ignition/modules/TransferExternalVerifier.ts @@ -0,0 +1,32 @@ +/// + +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +const TransferExternalVerifierModule = buildModule( + "transferExternalVerifier", + (m) => { + const transferExternalVerifierZKTL = m.library( + "contracts/verifiers/TransferExternalVerifier.sol:ZKTranscriptLib", + { + id: "TransferVerifierLib", + }, + ); + + const transferExternalVerifier = m.contract( + "TransferExternalVerifier", + [], + { + libraries: { + ZKTranscriptLib: transferExternalVerifierZKTL, + }, + }, + ); + + return { + transferExternalVerifier, + transferExternalVerifierZKTL, + }; + }, +); + +export default TransferExternalVerifierModule; diff --git a/contracts/package.json b/contracts/package.json index 395ef0a..e1f1314 100755 --- a/contracts/package.json +++ b/contracts/package.json @@ -2,15 +2,13 @@ "name": "contracts", "scripts": { "test:gas": "hardhat test --gas-stats", - "build": "./scripts/bash/build-and-export-circuits.sh", - "build-ipfs": "ts-node scripts/build.ts", - "deploy": "ts-node scripts/deploy.ts" + "build": "./scripts/bash/build-and-export-circuits.sh" }, "type": "module", "devDependencies": { "@aztec/bb.js": "3.0.0-nightly.20251104", "@aztec/foundation": "^0.87.8", - "@noir-lang/noir_js": "1.0.0-beta.15", + "@noir-lang/noir_js": "1.0.0-beta.16", "@nomicfoundation/hardhat-ignition": "^3.0.5", "@nomicfoundation/hardhat-ignition-ethers": "^3.0.5", "@nomicfoundation/hardhat-toolbox-mocha-ethers": "^3.0.1", @@ -26,7 +24,7 @@ "eciesjs": "^0.4.16", "ethers": "^6.15.0", "forge-std": "github:foundry-rs/forge-std#v1.9.4", - "hardhat": "^3.0.13", + "hardhat": "^3.1.2", "mocha": "^11.7.5", "typescript": "~5.8.3" }, @@ -34,10 +32,10 @@ "typescript": "^5.0.0" }, "dependencies": { - "shared": "workspace:*", "axios": "^1.7.9", "clear": "^0.1.0", "form-data": "^4.0.0", - "merkletreejs": "^0.5.1" + "merkletreejs": "^0.5.1", + "shared": "workspace:*" } } diff --git a/contracts/scripts/bash/build-and-export-circuits.sh b/contracts/scripts/bash/build-and-export-circuits.sh index 7100ff1..543f7a4 100755 --- a/contracts/scripts/bash/build-and-export-circuits.sh +++ b/contracts/scripts/bash/build-and-export-circuits.sh @@ -4,7 +4,7 @@ ORIGINAL_DIR=$(pwd) echo "$ORIGINAL_DIR" -echo "building deposit verifier (1/3)" +echo "building deposit verifier (1/4)" cd ../circuits/deposit/ nargo compile @@ -22,7 +22,7 @@ sed -i '' 's/contract HonkVerifier/contract DepositVerifier/g' ../../contracts/c echo "Deposit copied to contracts/verifiers/DepositVerifier.sol" # ------------------------------------------- -echo "building deposit verifier (2/3)" +echo "building deposit verifier (2/4)" cd "../transfer" @@ -39,7 +39,24 @@ echo "transfer copied to contracts/verifiers/TransferVerifier.sol" # ------------------------------------------- -echo "building withdraw verifier (3/3)" +echo "building transfer external verifier (3/4)" + +cd "../transfer_external" + +nargo compile +bb write_vk -b ./target/transfer_external.json -o ./target --oracle_hash keccak +bb write_solidity_verifier -k ./target/vk -o ./target/contract.sol + +mv ./target/contract.sol ../../contracts/contracts/verifiers/TransferExternalVerifier.sol || { echo "Error: Failed to copy contract.sol"; exit 1; } + +# Replace 'contract HonkVerifier' with 'contract TransferExternalVerifier' in the generated contract +sed -i '' 's/contract HonkVerifier/contract TransferExternalVerifier/g' ../../contracts/contracts/verifiers/TransferExternalVerifier.sol + +echo "Withdraw copied to contracts/verifiers/TransferExternalVerifier.sol" + +# ------------------------------------------- + +echo "building withdraw verifier (4/4)" cd "../withdraw" diff --git a/contracts/scripts/bash/get-gate-counts.sh b/contracts/scripts/bash/get-gate-counts.sh index 94fdf49..1c086bb 100755 --- a/contracts/scripts/bash/get-gate-counts.sh +++ b/contracts/scripts/bash/get-gate-counts.sh @@ -9,9 +9,9 @@ bb gates -b ../circuits/deposit/target/deposit.json -v -s ultra_honk echo "----------------------------------" echo "Transfer circuit gate count:" -bb gates -b ../circuits/transfer/target/transfer.json +bb gates -b ../circuits/transfer/target/transfer.json -v -s ultra_honk echo "----------------------------------" echo "Withdraw circuit gate count:" -bb gates -b ../circuits/withdraw/target/withdraw.json +bb gates -b ../circuits/withdraw/target/withdraw.json -v -s ultra_honk echo "----------------------------------" diff --git a/contracts/scripts/bash/verify-contracts.sh b/contracts/scripts/bash/verify-contracts.sh index 3a6f203..7f86ca9 100755 --- a/contracts/scripts/bash/verify-contracts.sh +++ b/contracts/scripts/bash/verify-contracts.sh @@ -1,12 +1,12 @@ #!/bin/bash # Verify all contracts deployed to a chain -# Run from the contracts/ directory with: bash scripts/bash/verify-sepolia-contracts.sh [--chain CHAIN_ID] -# Example: bash scripts/bash/verify-sepolia-contracts.sh --chain 11155111 +# Run from the contracts/ directory with: bash scripts/bash/verify-contracts.sh [--chain CHAIN_ID] +# Example: bash scripts/bash/verify-contracts.sh --chain 11155111 # Default chain ID (Sepolia) -CHAIN_ID="11155111" -NETWORK="sepolia" +CHAIN_ID="1" +NETWORK="mainnet" # Parse command line arguments while [[ $# -gt 0 ]]; do @@ -62,9 +62,12 @@ fi DEPOSIT_VERIFIER_LIB=$(jq -r '."depositVerifier#DepositVerifierLib"' "$DEPLOYED_ADDRESSES_FILE") TRANSFER_VERIFIER_LIB=$(jq -r '."transferVerifier#TransferVerifierLib"' "$DEPLOYED_ADDRESSES_FILE") WITHDRAW_VERIFIER_LIB=$(jq -r '."withdrawVerifier#WithdrawVerifierLib"' "$DEPLOYED_ADDRESSES_FILE") +TRANSFER_EXTERNAL_LIB=$(jq -r '."transferExternalVerifier#TransferVerifierLib"' "$DEPLOYED_ADDRESSES_FILE") DEPOSIT_VERIFIER=$(jq -r '."depositVerifier#DepositVerifier"' "$DEPLOYED_ADDRESSES_FILE") TRANSFER_VERIFIER=$(jq -r '."transferVerifier#TransferVerifier"' "$DEPLOYED_ADDRESSES_FILE") WITHDRAW_VERIFIER=$(jq -r '."withdrawVerifier#WithdrawVerifier"' "$DEPLOYED_ADDRESSES_FILE") +# TransferExternalVerifier transferExternalVerifier#TransferExternalVerifier +TRANSFER_EXTERNAL_VERIFIER=$(jq -r '."transferExternalVerifier#TransferExternalVerifier"' "$DEPLOYED_ADDRESSES_FILE") COMMBANK_DOT_ETH=$(jq -r '."commbankDotEth#CommBankDotEth"' "$DEPLOYED_ADDRESSES_FILE") # Verify addresses were extracted @@ -81,36 +84,45 @@ echo "========================================" echo "DepositVerifierLib: $DEPOSIT_VERIFIER_LIB" echo "TransferVerifierLib: $TRANSFER_VERIFIER_LIB" echo "WithdrawVerifierLib: $WITHDRAW_VERIFIER_LIB" +echo "TransferExternalLib: $TRANSFER_EXTERNAL_LIB" echo "DepositVerifier: $DEPOSIT_VERIFIER" echo "TransferVerifier: $TRANSFER_VERIFIER" echo "WithdrawVerifier: $WITHDRAW_VERIFIER" +echo "TransferExternalVerifier: $TRANSFER_EXTERNAL_VERIFIER" echo "CommBankDotEth: $COMMBANK_DOT_ETH" echo "========================================" echo "" # Verify libraries -echo "Verifying DepositVerifierLib (ZKTranscriptLib)..." -npx hardhat verify --network "$NETWORK" "$DEPOSIT_VERIFIER_LIB" --contract contracts/verifiers/DepositVerifier.sol:ZKTranscriptLib +# echo "Verifying DepositVerifierLib (ZKTranscriptLib)..." +# npx hardhat verify --network "$NETWORK" "$DEPOSIT_VERIFIER_LIB" --contract contracts/verifiers/DepositVerifier.sol:ZKTranscriptLib -echo "Verifying TransferVerifierLib (ZKTranscriptLib)..." -npx hardhat verify --network "$NETWORK" "$TRANSFER_VERIFIER_LIB" --contract contracts/verifiers/TransferVerifier.sol:ZKTranscriptLib +# echo "Verifying TransferVerifierLib (ZKTranscriptLib)..." +# npx hardhat verify --network "$NETWORK" "$TRANSFER_VERIFIER_LIB" --contract contracts/verifiers/TransferVerifier.sol:ZKTranscriptLib + +# echo "Verifying WithdrawVerifierLib (ZKTranscriptLib)..." +# npx hardhat verify --network "$NETWORK" "$WITHDRAW_VERIFIER_LIB" --contract contracts/verifiers/WithdrawVerifier.sol:ZKTranscriptLib + +echo "Verifying TransferExternalVerifierLib (ZKTranscriptLib)..." +npx hardhat verify --network "$NETWORK" "$TRANSFER_EXTERNAL_LIB" --contract contracts/verifiers/TransferExternalVerifier.sol:ZKTranscriptLib -echo "Verifying WithdrawVerifierLib (ZKTranscriptLib)..." -npx hardhat verify --network "$NETWORK" "$WITHDRAW_VERIFIER_LIB" --contract contracts/verifiers/WithdrawVerifier.sol:ZKTranscriptLib # Verify verifier contracts -echo "Verifying DepositVerifier..." -npx hardhat verify --network "$NETWORK" "$DEPOSIT_VERIFIER" +# echo "Verifying DepositVerifier..." +# npx hardhat verify --network "$NETWORK" "$DEPOSIT_VERIFIER" + +# echo "Verifying TransferVerifier..." +# npx hardhat verify --network "$NETWORK" "$TRANSFER_VERIFIER" -echo "Verifying TransferVerifier..." -npx hardhat verify --network "$NETWORK" "$TRANSFER_VERIFIER" +# echo "Verifying WithdrawVerifier..." +# npx hardhat verify --network "$NETWORK" "$WITHDRAW_VERIFIER" -echo "Verifying WithdrawVerifier..." -npx hardhat verify --network "$NETWORK" "$WITHDRAW_VERIFIER" +# echo "Verifying TransferExternalVerifier..." +# npx hardhat verify --network "$NETWORK" "$TRANSFER_EXTERNAL_VERIFIER" -# Verify main contract -echo "Verifying CommBankDotEth..." -npx hardhat verify --network "$NETWORK" "$COMMBANK_DOT_ETH" "$DEPOSIT_VERIFIER" "$TRANSFER_VERIFIER" "$WITHDRAW_VERIFIER" +# # Verify main contract +# echo "Verifying CommBankDotEth..." +# npx hardhat verify --network "$NETWORK" "$COMMBANK_DOT_ETH" "$DEPOSIT_VERIFIER" "$TRANSFER_VERIFIER" "$WITHDRAW_VERIFIER" "$TRANSFER_EXTERNAL_VERIFIER" echo "" echo "========================================" diff --git a/contracts/scripts/check-verifiers.ts b/contracts/scripts/check-verifiers.ts new file mode 100644 index 0000000..aa00fc9 --- /dev/null +++ b/contracts/scripts/check-verifiers.ts @@ -0,0 +1,21 @@ +import CommbankDotEthModule from "@/ignition/modules/CommbankDotEth"; +import { network } from "hardhat"; + +async function main() { + const connection = await network.connect(); + + const { commbankDotEth } = + await connection.ignition.deploy(CommbankDotEthModule); + + const depositVerifier = await commbankDotEth.depositVerifier(); + console.log("depositVerifier: ", depositVerifier); + const transferVerifier = await commbankDotEth.transferVerifier(); + console.log("transferVerifier: ", transferVerifier); + const withdrawVerifier = await commbankDotEth.withdrawVerifier(); + console.log("withdrawVerifier: ", withdrawVerifier); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/contracts/scripts/deploy-poseidon.ts b/contracts/scripts/deploy-poseidon.ts index 58b7826..7738ebb 100644 --- a/contracts/scripts/deploy-poseidon.ts +++ b/contracts/scripts/deploy-poseidon.ts @@ -10,6 +10,10 @@ async function main() { console.log(deployer.address); + const balance = await deployer.provider?.getBalance(deployer.address); + + console.log("balance: ", balance); + // As the poseidon2 huff bytecode was prebuilt, we have to assemble the factory like this const poseidon2HuffFactory = new ethers.ContractFactory( [], diff --git a/contracts/scripts/generate-and-test-relayer.ts b/contracts/scripts/generate-and-test-relayer.ts new file mode 100644 index 0000000..a342c3b --- /dev/null +++ b/contracts/scripts/generate-and-test-relayer.ts @@ -0,0 +1,165 @@ +import { getTransferDetails } from "@/helpers/functions/transfer"; +import { getNoteHash } from "@/helpers/functions/get-note-hash"; +import { getNullifier } from "@/helpers/functions/get-nullifier"; +import { getTestingAPI } from "@/helpers/get-testing-api"; +import { + createInputNote, + createOutputNote, + emptyInputNote, + emptyOutputNote, +} from "@/helpers/note-formatting"; +import { poseidon2Hash } from "@zkpassport/poseidon2"; +import { ethers } from "ethers"; + +async function main() { + console.log("🔧 Setting up test environment..."); + const { usdcDeployment, tree } = await getTestingAPI(); + + const assetId = await usdcDeployment.getAddress(); + const assetAmount = 5_000_000n; + + // Alice's credentials + const secret = + 2389312107716289199307843900794656424062350252250388738019021107824217896920n; + const ownerSecret = + 10036677144260647934022413515521823129584317400947571241312859176539726523915n; + const owner = BigInt(poseidon2Hash([ownerSecret]).toString()); + + // First, we need to create a deposit to have something to spend + console.log("📝 Creating input note..."); + const depositHash = await getNoteHash({ + owner: owner.toString(), + secret: secret.toString(), + asset_id: assetId, + asset_amount: assetAmount.toString(), + }); + + // Insert the deposit into the tree + await tree.insert(depositHash.toString(), 0); + + // Get merkle proof for the deposit + const merkleProof = await tree.getProof(0); + const leafIndex = 0n; + + // Create the input note to spend + const aliceInputNote = createInputNote( + assetId, + assetAmount, + owner, + ownerSecret, + secret, + leafIndex, + merkleProof.siblings, + merkleProof.indices, + ); + + const aliceInputNullifier = await getNullifier( + leafIndex, + owner, + secret, + assetId, + assetAmount, + ); + + // Alice's change note + const alice_amount = 3_000_000n; + const alice_note_secret = + 19536471094918068928039225564664574556680178861106125446000998678966251111926n; + + const aliceOutputNote = createOutputNote( + owner, + alice_note_secret, + assetId, + alice_amount, + ); + const aliceOutputHash = await getNoteHash(aliceOutputNote); + + // Bob's note + const bobOwnerSecret = + 6955001134965379637962992480442037189090898019061077075663294923529403402038n; + const bobOwner = poseidon2Hash([bobOwnerSecret]).toString(); + const bobNoteSecret = + 3957740128091467064337395812164919758932045173069261808814882570720300029469n; + const bobAmount = 2_000_000n; + const bobOutputNote = createOutputNote( + bobOwner, + bobNoteSecret, + assetId, + bobAmount, + ); + + const bobOutputHash = await getNoteHash(bobOutputNote); + + // Prepare inputs for transfer proof + const inputNotes = [aliceInputNote, emptyInputNote, emptyInputNote]; + const outputNotes = [aliceOutputNote, bobOutputNote, emptyOutputNote]; + const nullifiers = [aliceInputNullifier, 0n, 0n]; + const outputHashes = [aliceOutputHash, bobOutputHash, 0n]; + + console.log("🔐 Generating transfer proof..."); + const { proof: transferProof } = await getTransferDetails( + tree, + inputNotes, + nullifiers, + outputNotes, + outputHashes, + ); + + console.log("✅ Proof generated successfully!"); + console.log("📊 Proof size:", transferProof.proof.length / 2 - 1, "bytes"); + console.log("📊 Public inputs:", transferProof.publicInputs.length); + + // Prepare the payload for the relayer + const relayerPayload = { + proof: { + proof: ethers.hexlify(transferProof.proof), + publicInputs: transferProof.publicInputs, + }, + payload: ["0x", "0x", "0x"], // Empty encrypted notes for testing + }; + + console.log("\n🚀 Sending proof to relayer..."); + console.log( + JSON.stringify( + { + proof: { + proof: relayerPayload.proof.proof.substring(0, 100) + "...", + publicInputs: relayerPayload.proof.publicInputs, + }, + payload: relayerPayload.payload, + }, + null, + 2, + ), + ); + + try { + const response = await fetch( + "https://relayer-production-91b9.up.railway.app/tx", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(relayerPayload), + }, + ); + + const text = await response.text(); + console.log("\n📬 Response status:", response.status); + console.log("📬 Response body:", text); + + if (response.ok) { + console.log("\n✅ Relayer accepted and verified the proof!"); + } else { + console.log("\n❌ Relayer rejected the proof:", text); + } + } catch (error) { + console.error("\n❌ Error connecting to relayer:", error); + } +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/contracts/scripts/grant-role.ts b/contracts/scripts/grant-role.ts index f781c27..2e81bc5 100644 --- a/contracts/scripts/grant-role.ts +++ b/contracts/scripts/grant-role.ts @@ -12,12 +12,48 @@ async function main() { const recipient = "0x6e400024D346e8874080438756027001896937E3"; - const tx = await commbankDotEth.grantRole( - await commbankDotEth.DEPOSIT_ROLE(), + const depositRole = await commbankDotEth.DEPOSIT_ROLE(); + const gasEstimate = await commbankDotEth.grantRole.estimateGas( + depositRole, recipient, ); + const doubledGas = gasEstimate * 2n; + + // Get fee data and set higher priority fees for Sepolia + const provider = deployer.provider; + if (!provider) throw new Error("No provider available"); + const feeData = await provider.getFeeData(); + + // Use higher priority fees (3x) to ensure transaction goes through on Sepolia + const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas + ? feeData.maxPriorityFeePerGas * 5n + : undefined; + const maxFeePerGas = feeData.maxFeePerGas + ? feeData.maxFeePerGas * 5n + : undefined; + + console.log(`Gas estimate: ${gasEstimate.toString()}`); + console.log(`Using doubled gas: ${doubledGas.toString()}`); + if (maxPriorityFeePerGas) { + console.log( + `Max priority fee per gas: ${maxPriorityFeePerGas.toString()} wei`, + ); + } + if (maxFeePerGas) { + console.log(`Max fee per gas: ${maxFeePerGas.toString()} wei`); + } + + const tx = await commbankDotEth.grantRole(depositRole, recipient, { + gasLimit: doubledGas, + maxFeePerGas, + maxPriorityFeePerGas, + }); console.log(tx); + + await tx.wait(); + + console.log("done"); } main().catch((error) => { diff --git a/contracts/scripts/set-poseidon.ts b/contracts/scripts/set-poseidon.ts index e15f683..083b9c7 100644 --- a/contracts/scripts/set-poseidon.ts +++ b/contracts/scripts/set-poseidon.ts @@ -1,6 +1,19 @@ // sepolia 0x185D905Cd0262aDB6a5146C38AD6a718988272dc +// arb sepolia 0x7A8ee7caab52782547341c3A6a0aA29aC4f60Aa3 import CommbankDotEthModule from "@/ignition/modules/CommbankDotEth"; -import { network } from "hardhat"; +import hre, { network } from "hardhat"; + +const getPosedion = (chainId: number) => { + if (chainId === 11155111) { + return "0x185D905Cd0262aDB6a5146C38AD6a718988272dc"; + } + if (chainId === 421614) { + return "0x7A8ee7caab52782547341c3A6a0aA29aC4f60Aa3"; + } + if (chainId === 1) { + return "0xA09599efa9a31036D20a9eEF07C69E77937E784E"; + } +}; async function main() { const connection = await network.connect(); @@ -11,7 +24,16 @@ async function main() { const { commbankDotEth } = await connection.ignition.deploy(CommbankDotEthModule); - const posedion = "0x185D905Cd0262aDB6a5146C38AD6a718988272dc"; + console.log(connection.networkConfig.chainId); + + if (!connection.networkConfig.chainId) + throw new Error("ERRR missing chainId"); + + const posedion = getPosedion(connection.networkConfig.chainId); + + if (!posedion) { + throw new Error("missing poseidon"); + } const tx = await commbankDotEth.setPoseidon(posedion); diff --git a/contracts/scripts/test-relayer.ts b/contracts/scripts/test-relayer.ts new file mode 100644 index 0000000..4f79f49 --- /dev/null +++ b/contracts/scripts/test-relayer.ts @@ -0,0 +1,50 @@ +async function main() { + const exampleProof = { + proof: { + proof: + "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf00000000000000000000000000000000000000000000000b75c020998797da780000000000000000000000000000000000000000000000005a107acb64952eca000000000000000000000000000000000000000000000000000031e97a575e9d00000000000000000000000000000000000000000000000b5666547acf8bd5a400000000000000000000000000000000000000000000000c410db10a01750aeb00000000000000000000000000000000000000000000000d722669117f9758a4000000000000000000000000000000000000000000000000000178cbf4206471000000000000000000000000000000000000000000000000e91b8a11e7842c38000000000000000000000000000000000000000000000007fd51009034b3357f000000000000000000000000000000000000000000000009889939f81e9c74020000000000000000000000000000000000000000000000000000f94656a2ca48000000000000000000000000000000000000000000000006fb128b46c1ddb67f0000000000000000000000000000000000000000000000093fe27776f50224bd000000000000000000000000000000000000000000000004a0c80c0da527a0810000000000000000000000000000000000000000000000000001b52c2020d7462a349a10dbe493fc324b7b485fccab1c4ddd478a651df364cef54a65df08c76428c5f46146e5248d7bd609c2ed01a638937d8afe75bc443a356a94450177feb30723483524a2d5b19ad0e446e40e7a653056c46bb6714a56fa14c04380e1e3f20e068afbfcae51a37428635ee9bd3331c6783dd65092d4114cd124c72b23b1ab017a8b857c49be8310e4aa1a49163f98e9322109db7d560ed5ceca8074b652230fd9f6a6f693ccc4facfc72ab5f0a6e3d938197bb1cb72833332be89e20dd3fb2b535999c58b936b10c1ad6bad1a2a481549fb7247af8857f7668573f835bb220788693404b82a04965ebf82e2c91a59e62d216962fad8567b81448774802a542a65882844294ff4d7c7e5f42e35d8f0ac7b7aec56b7a8a3d1dda83d39d154ca236b79b09c36689dd0bd6d78f99b0037adca993e1cb606325f30de907f3f50380fdc4c7514f3f3753ee0cb4d8e15860d160569771d4708307930f20a8142ab151611a69ba7403de5e4bba1792a83aee214bd4bbacbe513650f93fd2f527aa508293304997399298002f7ffcae2136ddb7fb412d22a28f9ab90f1aececbe773632f530ffa6b2f5836bbe47a2a492c894ed257511cd6bb76b15d02415c2c4dc2f801dd127752e33440c7f949ccf49ffb7fa1fbdb6f0f2ea760054543e979adce4105bc733ae3a3a353ec2f4c02d8ae3adff591c03f881379391946d0af1fee9ffc2b69542435743e54ffed4c82cf0a77ed5dfbec86e13460d69590ce6fb7e94d0706d0c3931ffde14173112ad1e496a39a10559ae6c15053d018df0d6925b9d61f1f13372291e215c99eb6623d64dc175e6647c0ec5503c5040ee08b9d3080587402891f10980c7436f65080d97131ee6e914fee83659cf793ed949c93318417542a9f0d1dcb855d91dcf661f9e5097cc566dbb01dd2bcaa058523eafe8318660e28b80338de60b66606f205d7bb7d3b3609ae7cd832d2fce0a634a38fe4b1708b15458e54a7a5cd5110016cfc7d52885ba0fc13f26aaf0a676846aebb5a5628302ba93ba9ec3ead6bfd6f79778ef639a41e52d26c5bed5bd0a1baf7350390eda91059f6a895b0999a0f3259ba46c8026ca5e43676d610e8240f9ecffe5e5f870b2ac0636919c9ccf8cd1b79b12550400a49bbf841f5ef9a3e021f097dcb5e97651d0ace3993e8d082ccd39eb58f95b90530845a83493b21ec9ff002f9fb8084392205b4983650e8c7c2bd5a58da4a45bdce02b7a088037ed4076b660efa8bcb9e2c79e2765277de4a6ccc130b79744b46b82a54f69d327d68e14f4e61eef4128c1a10a067cbe70cfdf6b8f1147bee72b53260b331fce56e7910df8b2963c909b52c25c840e088b36313e935665fa1e1ce0cbf47b4b215bfc4a93507d7bc7c04f82d4530a13817bb403af736f6f66a08988152fafa6e70a390aba9932e5dd6c080008fef0234d73cf67f4c4f34e327d14ed3ae6c12d95e2227756d34f97d51a416144e65d4c008ac782e6bd969d13cd1de8cdc2b5333a873e3674fcce834f514640fc3efd55680f9cf9f95e2701ef5df545d8420fac69fada9162b27962239015e0300c3c7dc88f4890b9c3a9a5fe357581c3b004f7cfb99355aba1a349fb2a3ab25a08e075d53a37d8681ec67fcd4811d9b04be51035150f1ea3fda0a1c4e7f700824811a4ff098415f932f53e92ae17d003d75f15a67d06c5c6caeb7d788326814ce14b7223c09b19a260bc2261e7e6dfd3bf605458c00d73727be3461b54da518ec24ee81752582ca10e3ea57cf558df6027beed0090a3bd4a4144f12b958ff1f6258f89dd8d0f3c06bb8579a0f0f67686f54059dac87310c061f2190e7d5291105dca1eee51d6c0088e7196559d4635e4d647febda2fa745a5e0da2f8019482014d48b5bcac037025940dca8c4d7b2f783d3cff105407e8f12bb243c224f0629b6dc30921453dd09967c3173ccc464b82a8c5fb659a0a700a5fce36b6e83372ee08e2bdc9c0311b3ac15c9f3b544d336ec83780ff8c66b2069d732af67ec8f088c492f2e7be614742165035de171e3e7079cebee992de3beff2e8c2d8ffacb25dd929048008066bebebcc7307fb9c67488e8eaaae5316a9ce917b38acb30081ebce6abdfb987f3479db2ac554279072d47d2e9ac34fdbf636daff9171dac4f1fe52f7816b6bdd7567f22587500e4deadbd42f2d859199391ff90e28ed7545301110c6db7c8a7c2ee9feb603de01595c4fd39f457ea1bd9bfe48249c077800d11036eeffa35305f96c86952659e956e9ebbb107035036980ddc88f1d492b724296406f4b11890e04e47701b9931abefce0182b463e6b6bd453fe1774811a59e2a2e042cfd2b3da0be1ae2559e564c5fc72b823cc44ac30b90e26acb1545b4d90c92c1ffa4a729b324f7da6569506daa875d25703e6f13951a5fafb21fa7326610354b9a27dc84d827d161a990b9601f5a43ef19f53f8fe4f9802c183573b2cd1a3079e0b7699275cf601bf6b870a3ab5cf7ac78b0a165493c304352b056d69e25df03ef5abb3684cbc1d82c393a93eeac5f4afdf7dcdfe41be394480b279a23288be1f9519b5ae90f12e05ae96ed481e9506ddefaa6c3377910e8b0a95b52bb2e931002daca55c27d924bcaaa236763271a49b9438238645a71d906e754752817f144fbff373635ca2a86a7cbdcf7d10f442c82f612f67ec1f83b54ebb2f83e00d2ffb965bfd94379f90b117ba2e3e5c64d718b2994ad116c3ce2eccbb8b9a00a18c0c8566fceebc3af4fd29384191235d75fb9c8c91ea1411774c51e5c53750c9beee8b06ca8b7b0b2bd54e6d64f9f19f8baca9a344abebd3c270899c21673224a946fd6717cf967991969d0202f2a734cb2c899332fbd9a1295ff9a9483891399bec6ffc7045da7a3710bde4141dffd4197312a40dffa7a821142b92cebbc0a36524cc30a195750b3185bfce28b39f5349002adfbdc6aece6cf5e511747640f73a72c9bc089a9d944bfb6ff0132c02c916057cf51998c7fcd1e46bdfcd1bf0f2566d8793d282b410aba6b52fc78617b0035588853f7574fd1fa403092e40d284b118ab6ba6233d85e876e389d776199f60ba6fbe3a0a46af7108ad8f2e8171e24e575c7e0be46650d5284dcc709f083f826b449f8151eee3c4d0878cca80205a23fa0b609d458d2fd049ad73cf26866336fe695681c883071ddc54d1dab8e2c000d89cf1906cfe572c8922a23dedd77c04a69e9f4194dc06933b17ecb704b06c33d074a5253e5a475dc734789dc7a5ddaa0360b1dd305f1b00e04df05a52017ea9dc58bbc0371f6e576b2e72632e76527a74dad9a38601595390a8e3e47fd21f5fe14d750bb0afc9b89044d1023f8743f6c79bcdb5a0bf60e87ce948cd8f419426eaf2263533419a6ad88cea2b01799e0854a0bc658afbe9fd10edf6a59172e7c7bc8146237b8fa6decc991efbaf225acfea00c340a47939961e30af3ed3f03701af0e51bc4658aa277204e58f5df1f4f959ed72af030ea64640951484b681b5362ebaf6472400c9ac38de828da23fae62682282c9423006908402754ee452cda7b7088b4d4c87b949ac28989b1beac8dda13a04cbadf99e56ca0756fe2232993dba5242bb3acb8bd336c51201ed46c7a8bb382714ff1560a2f8a54e85a210f1b086f65946774e1d5ecb73a19c3efe0955f104ea737a16c02e4094dec243b2e4a0a27990343c0e4f8f08cf6ddc117390a0ee763696539ed9503c14e8be03019ac631c0bfef07c2de211eb761289c829bac3b20f29da2dc419a29d7a44d1501e5c0eb7ac5e01486863276e5b14407f62b58fb57e7350d7f4ce09532b57aa2b2803c1555c9c511b8e037df05066a864a265bfdc80c777eefc4ddc4c2f9f2ebe109f01acdf95905389683a853c6cd328d870364f79cb3602bdec9eb32feb78aa02a42e5dc80fd2d2bf4010fdd65d83b9002b90e27e4b4f6145ea4ea3ffdc31e226ead77cad37e02653dd3feaf03fc381479c169e379f0cddaf7ee7857c2946e92f232796645de2cf33fea12c46f7dccaad2044fcca78fc2a42fe167efbdd6e591c9ca5d4dc34f04926a93529692bb1835ac9597f7ab12d43fb8937ec305a1b2f2e19c694e7ca9c247ca35de17e0499aad11018f1bbc7df4010427b67b8e35bfe0a78e4e373cedbe8848454a370046a48e34db4832c409465a997318bf2ace5bd0535eea91f1ddb630a394e172a1ab95cbb965e91e7729a7419d4469afa1d118d125da6a63db214442e5bf57731e76a116c582a1f2226dcee528cb7816322f2c00f3a84d0ea641078e56cb0f26bf7127b05883dd5f0ddd0342c5c4ebb8de46f131a22bcec7e64c6a87d3ff4cdc7367cf1ea86fd04c1eb63073e3d16de41665cb721c2697f1dabbb35e0f75d913d881a7ab28ab99138086af3f1538fee2b16559f258f6072b07050344d91da1ad26a9957026a3f4837a00ea505fd6eb0a7fa67240903ad6b1e3af710f511ba78a8f8988896d02103e6c7e7020ac9e5684dbf0d962230a7f48e76ee36a65991ceb7fc392ff746c89e7dc7af0a3448f8f53dfabded149da39a3bf4ad8fe8644783359979d5d9ae7543e3f1cf9e6d1aa09c3d0e26341911059fa66c137122cede4d90dd6397cc9f2ccc0813ee47dde68b715ebcc3832798d66c96fbb178de8951d8b137cbcf196e751f347c683d1b01b7fc2b0e2c161450d574800a461a45ab1df1d80a4bcadf7100b95c88de1c458a6fc46eccb44e06b282639930caf4c559f03f69fa4b33553f080876f8d88a1605f215441b16920d41a4d28da113a0aba452359bf4759a8c793f2bfa7b43178cd1b7cee0ec96fc161a96ee77b08448c8b8f90fa6d4825d723179cdb3de3f53a9b5f3283f5d92c90d647cbe0b93bf9b6220a4f59d7c13987831ecbdcc8ed115d285cf12bb95a57e09abcfc4526277303c804023c6a65121b9b7d62ba5fcbec26b17bb4b97a53d7b0ec7314bf09c34e466552038635895cd722a03253833a937a24a16dbb0f48b33177dc35b8d5286c7c11ab4669a342df73ef04ae6611f31eeeceb1a78be60a65b27fc4d79768b753f8b83502b7632f8932b00deb1ae8b22f7fd63f996a5c866f5302669a4a2f07a225cc052ccb77cad2e01c61db8e391f88e016187530b717ff02283217ce0e557e2cb5f17ef99b9936c67357e94c2818e8b21df80b9cb88fa8a0c94d240407d070ee6d988f1a6b20839c871eae8e09d0ce0982ad4cc78dc47d60234af477e1928fa8b59ae11babd837c2a141290c2bee0d5650731f8e3e4363712aad1436f1a12bfafd174989e931fbc68659dd71cca42ff1a49ed3cc51b35d51f80a57a6c9e97f02ec64b17f5e37979d727211652d70a06fdcbad12ca52c80f0e2261075b7f0d55f755033e9b4676f67fb1287b892a297f4a7906844b4de3850ab4c551132be1992ee829fa45eb24cc6934f08545b1cdf96d7d06acefeff3972bff8129da8f48b078df00d09f4ec2d490f8e93f29ccda9042bbf2f746fe5875154cc53f6742829c894d6bfe0b1ae210cf45e0da485f2acdcbd652f09878db3f20cbac070990b1a5da5274dcee76fd0c1b3b2bf099aac454bc32622036feb2d80b9d145eb4a44af05a8c09c96c91c5c0a1abb77ad4534aed369ab3ce118b70dd2da18d0f8fdb7cddc8093f997280d9ba7147c989614bf30b28cd58524ce9b7bf1aabbe01dd2a08691ce6a868b375c4e2229b79a89d355d0ec61f4a58917e26bd06ba180dcb8e66a92a4e12ac00e608134db4b045a5178357af2ac0841961c4af0da872e718c49d663fb29a32c1390a3fe24dc9967d2cd8e902643d608b7e7b90007d3b688c6070226dbeebdbb3d99a09e6656cae680d21362f669d7e3d6b34561f68cbdfeaaa23c6d52aa2c25e66efaae6020f3a30c34f3f0acc832336c6ed7c2a572a57d39873b2447e642974915d733d0580b22cb9408d83b794291dd54ce410117fd5599b45b4dc5987f45456f10d40d7084814568a2457e49db07c7370012f04283163556a7a622e4eb3e9638a64f7ae999039e0500824151bec0c8a4204051f974d96cad9153ea97402e28ab028ec09af5d85aa1f9c98944db085a973dc20f217c688b26ef79c5ea73be2d8d46456fcd75ca4576d0828276c77a273a6e5179e52402371986db57fac6d7ffac9300d452b3b117fb899caae5caff096892c286cfc652efaa75f0dce0ca8b0252c6e10ade19d4d2bb314418a73f63b662ffd2cf5c8760089319379601f343eb951a74fda268298abdedfb8d4db99cd2d13711a65629319c68919a6a1814b4b4ed6d13580650116b7cf3a561da52a042c576726765883e01ac6b1d7358143baad354fe319f19f93c9831d8c0eba6c11ae94b92943ad8f24e337f593c8b7be472710e07e070ca934daf97e72638e077ccd2bca2f3f36a7ff615d1b6b6e3a55dc0a882017778d9ed9f1795e04899dd148c3ddb2205b9f02933a9ab6ff83848de47627701798f97a84eb47a32221b4dd615a28bc1315e005610d88c47141906286811ad885616537e8ca77c28b43d9f31702028522b1145a21fd6dabfc67a605eba166710aff7726b46764ca206feb07d370c4420ae3d5d7af8316d3a8fbbc37972ae98a572d068897503331f245dd5ad04058200f2b5138c4be46a0a93d3069eed89347d7ded3689432278be3ac31a95d67b74f265a0f7d4c72749d52e7044c28faadf956ee6b22ba64fffc5400d99c19f25d2d0163c93123a7d51e922c618e02ce56a00e8104f58bb5bd145fa9c0007dd72a931b04a6318704f7b853e4fe03a27b77871e84a7e8b14b9e6a1104bce1a09a004f0de113266a4043225f90211e990125d949ae6c141159b3a293a040cd7c98b9b91b131fef0f7f659980d43955fd24df75105c284f7575b229a85466c2723089ca1d87599f0ca990f639eb1151bfcd01b3f64544d30db248498943e2b8fb3d6a16044bef8cf0bb27ca381c12012263b8e3ae3dd2cfdba580d710429667e68d41d72eec66e63073598b0cacca133690475b15ce82b3e0c304814d2648cb2c718a0e17ea44974f58c5e33efe3345db225a3de7dddef6391302401d3d467fedc65f6129a7c32e3b783defe6ad85d3740e999946e6cfc81da3289263b849e98af916b208add39ad54c7bf95eacb5a0c6f5a2bf2f78c0f85010527bf16a3862889b41052216fd68ddfa7c84fdfab68c7d6909d6aa90e734b7743fe2baebed1ac3c71cfe065f015200bba798d66c4085c1489f92256c50a04d0e078693cddc5393c5dcd91ddbe1f5534d95de22b165b14d613fd9e1baae4a72342c50a8550d5b36ad71f50178500a80d8870fe9fe3f31ee952e3bf7fe2f462592e629b1fdb28baa24fdde04fc4b5e4af14e7a11093eea95afa79a67ec040c791a342c7d9cf5104e8efefe07b1fa47fce1848ca6e966ba43d714ee82e0841fcefeb52f849723268f97562e02c2911c36f90526b917815fdc2273b7e81d3e88b144f22c1ae5eed929e4be2328809801876f5a2b826e2e355ec75f785aac66b2718566ec764fc84b65302dc12763525acc34635cbfb4ee630a048daa5cc4ab5f417728aa0f8f9477a724c500281d8c5e7edf2581c4a68b41a2b3943bb09b9fe6e9fdcf2e4f5a87cfd1d96561159d64325eeae5425a80d554702c680e96ef8d55269ae7d811783d63fac2926529c6714ed5b90a82f7db96c5dd2c9fbe7fcf75969680061947f9cba7e5598f932322a2d1ee46f4e762d65d600ffe22674369c08097202d88facbef5a215ee23f0dd23afc9863ec01d44a7296f0edb882d9146530bacaf6c680491f65d836585d2f06436b24dac834a545a8034e5f7a300e13fef6da19709621de34623ceb88d30fe6a7c897c202101b394bbcacb79f5a52f6f3deafa41daa72b172652b194ae61c09a5894271b92ea9b81627bc5fe73250c435159c4319d756c069a0af9786ac252e4ba2746cc2ffaccb15a83c55ba203f8c897755da25a587e9ad91538e0c7a295fafd522c9a030de06260bda78296d3f16ddf8f120f5c315441eda3db62f3302e9dd4cf2262929ab36d4d8edda03d4fe74e758089147053d4f938ec90064781f0122d434d7982646c67e1c301cdea6b8e84bbc59383b42705efa324ae22adf1c64bd9f83c354dd9f8e87012bd75a83cd2724f9ae762341985c3099854cd1c92c60bbb6b575d2986c96a3958d1e2f6d3b7be13e7d3cbfc2a8d982815db0881c2a6dfc8c306770f2c192383ab84f6f1f4d6faaaa02921235510d54c4a506a28c258c897f650c738be5b590077ff08bd364b547107728c5893358e18747712f8a0db239b7b58aff461055f78d636495182f1143d236414cd81782bb084e6911672d35c5dfbb5c19a3391ae5f3e9c19effc1a744d1e5feb8416f8bd1b4f4bb4d09120805b79962c5e510b669538d27a8fbdb76e5c237961d3cfed2c61fd2bf199b19c4fb2555ba59bdc281a36b8dce57e8080a95184f266b2920087ab421d96aeb13e5481bc6bb5571678cae0f0642d1e5742897b7590ec5d7f848f6534e601eee1161d34db7cae1d8696b239b9b549bc2d19a03aa24b2e9b7d9f5fc6ac38f7f2f20c10d49beabbb584170828e6482a70bd4752949bcd6c4815ab270d50e1999eb0fa9f2b6b7526ca89d528a648978a83702706134a9f99ad21c9e97a28df242ef0c0811841d7e249bfeea91d033adc0574fe216e2ada703e987aa29d6d036f0d12e8132ee48253125b33eefc60b4a2b341c9325b30547dca6eb12bbb7e4b547a726a82f960474ced8aec65a4831cb79d5991e17f2e11a924a563f9cec2b3a0ac704c4ec657421cfcd303241d1c58b6638738f8f8f3680864976126428c03d028e2f418809210003a36494af5ce6f35c26a881fa209bc87bc8e9cdb9dbe0996d1207ae5cc4225fd76037601b415fb0af4a3ba59a2612e6c811e5e7ebd6cdd4487d0a42a261ede07aea8f30fb3c87ae0a38ec736bd97514752240698e471db652e917878ee8cd382844c708bc920330ac1d3a430ac0f38266034842e140818ea09627291587eb7ed56a94b9f747bf14530e337908b0aabe9025f733e0d9dc7b2ad318d71c38a7b65f2b4408eef238ba6afbc097c3ad2a20b79b0cbf41822cce17f70be55a6bd07ecabdefccdf6edb55834e191b121050a2f8f83aee8ae4218601a124446a2cf84c36ca9052f1724a46c8b6873f5b907754a680d86a8607d64b66e321eb5675f14e2e873bfe2c0da1fc45f0ef02a51643f17efbb6bfe569c1567f860213de5fa6c958dd219ad382b22133b2636a6e24a19cbac1d82ee2d47abdac1d2de64d25e0c90b50e8fae4c87782b118b4693bbe14f0997712df045a596fedf728a6f7275b299b8147fec7081b27a75d5ffb1d1021a97a7b366ac946246ce4fe22d1a2e8b0ca45c720aaa9e82da0b9d068a760ec8ad88fa6ee6009efa092b2ad2aa55330aa46f5f622aa43565cbdee580e56f5822362bad5acc57b897973b25a26d09ff878896c4f482a5d211f28a235de48d0aa69085e13371104efcecb64b401bd82c45186e09421bf1188b5878a6d35ece585e66a9b7b7c1cef511df074271f19c845efeeaa70ebdc0e662403b81497ae20c9e2452f2ac58dfae86071189312350851d6396257d940fc979ea08e686b3361d97737e9b7b6afc3ffe0a9ce580a7ad7614a04f82d94c230506fc738fab351bc3a05af642562a030e3635f3f1715418e4a600b79edba4b58d837b21fead26c4ca6ffac6bf0de19ef86b544a913072748a2267d6403bf29dbca31daf88a96e761dd66090c10d472be2ed47503ea156933e1ff638d6faedeac005a8bd2dcc2dd02af49e5c7b19148b16a03b2d99216f98ca091b949e77a760c5cb626ff433468c149586f5749a0b4f7d6e11521df2b3d1b61dad2f30f9ed0bb32e5718fbefe6bee2f3d555025993a0311e5d908bb0b377ab39c24046effc84b1c18758adabdbbdc2f0bb47551ac9d808a95c761e2073535017716ac073fa1e4073b28452d9fefa5e5bbb77b7d2712f43e2cfc089113606c5d54eb46539f84c4fd9dfd194f069d87c3ecd4eaabaa0c53ef6e475afa2a8c67a6f46be5cf02904b62aa3fedc578b4a80793878e931512cfbabdb3ae87056a59ce5da80c01ea992c3a5768cd9ea4a28941317d266f3ae38c89f39ae2321109f88a6308f05bfece1fb799b9f9a8f338e5920b8bd66ce1998f27222c21eb28c8cd57db896836f7d377ae1cbc6c0e3f9834cf9df3dfb47c5ab5a57f3d6f3522aa9ed561482577326f580e4768e12cb83da28efcac07364092a5e2543c1d0c0dbda5224fcfac0e26986a43487c018ed66f4dddccc5a0ef20f234be600b01a817fd49f8b7da85a1b84dfd07b568f06925cd469f40cc80ae72d89d8b8c0926a530224aa5ffdc64f6f563d92fc6955073cb0658b1e0dc33036b64bb662a9ae9470518cd484638b4badaeadd1f25b6319eb879b94c1a21c6a287823a45652c23b8161402abbc29a530ea4e364cef5da5126917995ada4a227fa77e7a75fcfa1a741f6f7c674b335bdfa6b538e7a3b3f2a700cd17839dde35837298a0e02be2757909f3241da1a4e24d92e1ff76372b10e21ebb41a3637ae1d6eb76b663666ed88c0a3e036cf6d3efc682fdcdd84f2cedc05ce57d253ca51c6f9b25d446b0c6897c3032668d420a08714b92e786194ec7df23504d6fd5db9f867007b1500045f85d000a932aa8eb664ec85379ea47e3ec2299440baa55dbd97c0aea2c19e16ad2a02211004c124addc72dd0332a3a6667638ed4ea23d0d7d1a38a51aa40db18cf8a2cdfc819d5fb704ef63d9ad606122b1dd0d8384b174f0716d301449efde6a85e21764513fdf969e2f24953afcb87261c5df1918035e9a2f93aad01b4d6bb60ed2bf36618e3a8878be628ab42426ad3c15cdbdacbee568c2148aa79263fe50f1a", + publicInputs: [ + "0x2a9d8db88e7746e2b09c436dd8cfc7fe72b44de0d556ccc175d1468de420850d", + "0x20d2932e53340899564163ba1bee05506b9089b1b490c769c061b3ceed0e4db4", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x2b7ec460c9871b96033cb675590ea0a5dd8d418a6c6be7220edadf0b2140ca00", + "0x163dc03d298b3bbff7ad9d079e37549693100ed6d27052fb888624889d3e6dee", + "0x0000000000000000000000000000000000000000000000000000000000000000", + ], + }, + payload: [ + "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000104307830346434663836396337346137313039396565353165376137656338373030646464616261663662656563353534616436643333386537616632623739636338613539353738626231646536396162386532356239363364383635383736373031316663633534396231356235373834633236333766666538363631613664366565653665653663316438356430643766646165663732303162653330626234316234633164386137633130336234303938313834356139343565323130333831396265623430376332366233376534636333353863376238363838666565633663313739373462383337633231623939333763356164323333643334383136313900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d313038313231383635343239353536343738323734373433373236353139363732303730343538363131373438303533373131383031373138303133343534343835353332383533383638303600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078396645343637333636373964324439613635463039393246323237326445396633633766613665300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073330303030303000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000104307830343763613135316665393739613834313931363763326133323734386465623366383463393330313434656436313061363936633665373464636633366336663861663364373135323037303630623033623962346439613231643063636333613165343630306662616661306638663233363666656164666331323833623563393633303536303734343461333731626561396438336133313962386431343731393438636235616561613535633234623163373364366434393234376331343333353133623863623664613734333432366166343761353665613930383934376637623965376332363666663730653330333131393631386239653238303100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c363836383937333731393932313738353233363732373134343531373836383736383636343733343233313230383039373639353533303638383030333936303038353635343339323232360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078396645343637333636373964324439613635463039393246323237326445396633633766613665300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073230303030303000000000000000000000000000000000000000000000000000", + "0x", + ], + }; + + // Send the proof to the relayer + try { + const response = await fetch("http://localhost:3000/tx", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(exampleProof), + }); + + const text = await response.text(); + console.log("Response status:", response.status); + console.log("Response body:", text); + + if (response.ok) { + console.log("✅ Relayer accepted the proof!"); + } else { + console.log("❌ Relayer rejected the proof:", text); + } + } catch (error) { + console.error("Error connecting to relayer:", error); + } +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/contracts/test/transfer-external.test.ts b/contracts/test/transfer-external.test.ts new file mode 100644 index 0000000..469a1ab --- /dev/null +++ b/contracts/test/transfer-external.test.ts @@ -0,0 +1,182 @@ +import { getDepositDetails } from "@/helpers/functions/deposit"; +import { getNoteHash } from "@/helpers/functions/get-note-hash"; +import { getNullifier } from "@/helpers/functions/get-nullifier"; +import { + createDepositPayload, + getTransferExternalDetails, + transferExternal, +} from "@/helpers/functions/transfer"; +import { getTestingAPI } from "@/helpers/get-testing-api"; +import { + createInputNote, + createOutputNote, + emptyInputNote, + emptyOutputNote, +} from "@/helpers/note-formatting"; +import { NoteEncryption } from "@/helpers/note-sharing"; +import { PoseidonMerkleTree } from "@/helpers/poseidon-merkle-tree"; +import { poseidon2Hash } from "@zkpassport/poseidon2"; +import { ethers, Wallet } from "ethers"; +import { expect } from "chai"; + +describe("Testing Transfer External functionality", () => { + let Signers: ethers.Signer[]; + + let commbankDotEth: ethers.Contract; + let tree: PoseidonMerkleTree; + + let usdcDeployment: ethers.Contract; + + let deployer1Secret: string; + + beforeEach(async () => { + ({ Signers, usdcDeployment, commbankDotEth, tree, deployer1Secret } = + await getTestingAPI()); + }); + + it("testing transfer external functionality - internal note + external withdrawal", async () => { + const assetId = await usdcDeployment.getAddress(); + const assetAmount = 5_000_000n; + + const secret = + 2389312107716289199307843900794656424062350252250388738019021107824217896920n; + const ownerSecret = + 10036677144260647934022413515521823129584317400947571241312859176539726523915n; + const owner = BigInt(poseidon2Hash([ownerSecret]).toString()); + + // create the ZK proof + const { proof: depositProof } = await getDepositDetails({ + assetId, + assetAmount, + secret, + owner, + }); + + await usdcDeployment.approve( + await commbankDotEth.getAddress(), + assetAmount, + ); + + // create encrypted payload for the deposited note + const depositPayload = await createDepositPayload( + { + secret, + owner: owner.toString(), + asset_id: assetId, + asset_amount: assetAmount.toString(), + }, + Signers[0], + ); + + await commbankDotEth.deposit( + assetId, + assetAmount, + depositProof.proof, + depositProof.publicInputs, + depositPayload, + ); + await tree.insert(depositProof.publicInputs[0], 0); + + // now we have deposited we can spend + // get the merkle proof to spend our input note + const merkleProof = await tree.getProof(0); + const leafIndex = 0n; + + // create the input note to spend + const aliceInputNote = createInputNote( + assetId, + assetAmount, + owner, + ownerSecret, + secret, + leafIndex, + merkleProof.siblings, + merkleProof.indices, + ); + + const aliceInputNullifier = await getNullifier( + leafIndex, + owner, + secret, + assetId, + assetAmount, + ); + + // ALICE CHANGE NOTE DETAILS + const alice_owner = owner; + const alice_amount = 3_000_000n; + const alice_note_secret = + 19536471094918068928039225564664574556680178861106125446000998678966251111926n; + + // Bob gets 2 USDC withdrawn to his external address (put as FIRST output) + const bobExternalAddress = await Signers[9].getAddress(); + const bobAmount = 2_000_000n; + const bobOutputNote = createOutputNote( + 0n, // owner not needed for external withdrawal + 0n, // secret not needed for external withdrawal + assetId, + bobAmount, + BigInt(bobExternalAddress), // external address - this will be withdrawn + ); + + // Alice keeps 3 USDC as internal note (change) - put as SECOND output + const aliceOutputNote = createOutputNote( + alice_owner, + alice_note_secret, + assetId, + alice_amount, + 0n, // no external address - this is an internal transfer + ); + const aliceOutputHash = await getNoteHash(aliceOutputNote); + + const inputNotes = [aliceInputNote, emptyInputNote, emptyInputNote]; + const outputNotes = [bobOutputNote, aliceOutputNote, emptyOutputNote]; // Bob first, Alice second + const nullifiers = [aliceInputNullifier, 0n, 0n]; + const outputHashes = [0n, aliceOutputHash, 0n]; // Bob has no hash (external), Alice at index 1 + + // Exit parameters match the outputNotes indices + const exitAssets = [assetId, 0n, 0n]; // Bob at index 0 + const exitAmounts = [bobAmount, 0n, 0n]; + const exitAddresses = [BigInt(bobExternalAddress), 0n, 0n]; + const exitAddressHashes = [ + poseidon2Hash([BigInt(bobExternalAddress)]).toString(), + 0n, + 0n, + ]; + + const { proof: transferExternalProof } = await getTransferExternalDetails( + tree, + inputNotes, + nullifiers, + outputNotes, + outputHashes, + exitAssets, + exitAmounts, + exitAddresses, + exitAddressHashes, + ); + + // Only encrypt the internal note (Alice's change at index 1) + const aliceEncryptedNote = await NoteEncryption.createEncryptedNote( + aliceOutputNote, + new Wallet(deployer1Secret), + ); + + // Check Bob's balance before withdrawal + const bobBalanceBefore = await usdcDeployment.balanceOf(bobExternalAddress); + + await transferExternal(commbankDotEth, transferExternalProof, Signers[10], [ + "0x", // Bob's note is external (index 0), no encrypted payload + aliceEncryptedNote, // Alice's internal note (index 1) + "0x", + ]); + + // Only insert the internal note into the tree + await tree.insert(aliceOutputHash.toString(), 1); + + // Verify Bob received the external withdrawal + const bobBalanceAfter = await usdcDeployment.balanceOf(bobExternalAddress); + + expect(bobBalanceAfter).to.equal(bobBalanceBefore + bobAmount); + }); +}); diff --git a/contracts/types/notes.ts b/contracts/types/notes.ts index 1bbab04..bab8f16 100644 --- a/contracts/types/notes.ts +++ b/contracts/types/notes.ts @@ -1,19 +1,12 @@ -export interface DepositNote { - assetId: string | bigint; - assetAmount: string | bigint; - secret: string | bigint; - owner: string | bigint; -} - export interface InputNote { - asset_id: bigint | string; - asset_amount: bigint | string; - owner: bigint | string; - owner_secret: bigint | string; - secret: bigint | string; - leaf_index: bigint | string; - path: bigint[] | string[]; - path_indices: bigint[] | string[]; + asset_id: string; + asset_amount: string; + owner: string; + owner_secret: string; + secret: string; + leaf_index: string; + path: string[]; + path_indices: string[]; } export interface OutputNote { @@ -21,4 +14,5 @@ export interface OutputNote { secret: string; asset_id: string; asset_amount: string; + external_address?: string; } diff --git a/eslint.config.mjs b/eslint.config.mjs index 30e297b..e5f12e1 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,3 +1,6 @@ +// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format +import storybook from "eslint-plugin-storybook"; + import eslint from "@eslint/js"; import tseslint from "@typescript-eslint/eslint-plugin"; import tsparser from "@typescript-eslint/parser"; @@ -51,4 +54,5 @@ export default [ "**/out/", ], }, + ...storybook.configs["flat/recommended"], ]; diff --git a/indexer/.gitignore b/indexer/.gitignore index 4cb9661..3e3a844 100644 --- a/indexer/.gitignore +++ b/indexer/.gitignore @@ -34,3 +34,4 @@ logs *.gen.ts build .env +dist/ \ No newline at end of file diff --git a/indexer/config.yaml b/indexer/config.yaml index e491b68..8505c79 100644 --- a/indexer/config.yaml +++ b/indexer/config.yaml @@ -1,19 +1,29 @@ # yaml-language-server: $schema=./node_modules/envio/evm.schema.json name: envio-indexer +contracts: + - name: commbankdoteth + handler: src/EventHandlers.ts + events: + - event: LeafInserted(uint256 indexed leafIndex, bytes32 indexed leafValue) + - event: NotePayload(bytes encryptedNote) + - event: NullifierUsed(bytes32 indexed nullifier) + - event: RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) + - event: RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) + - event: RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) networks: - - id: 11155111 + # Ethereum Mainnet + - id: 1 start_block: 0 contracts: - name: commbankdoteth address: - - 0x582E8C09955727112014B50A4eB3978697CDCB77 - handler: src/EventHandlers.ts - events: - - event: LeafInserted(uint256 indexed leafIndex, bytes32 indexed leafValue) - - event: NotePayload(bytes encryptedNote) - - event: NullifierUsed(bytes32 indexed nullifier) - - event: RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) - - event: RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) - - event: RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) + - 0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e + # Arbitrum Sepolia + - id: 421614 + start_block: 0 + contracts: + - name: commbankdoteth + address: + - 0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3 unordered_multichain_mode: true preload_handlers: true diff --git a/package.json b/package.json index c635755..da14624 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "scripts": { "dev": "VITE_RUNNING_LOCAL_INDEXER=true pnpm --filter envio-indexer dev & pnpm --filter client dev", "build": "pnpm --filter client build", - "build-ipfs": "pnpm --filter client build-ipfs", "build-contracts": "pnpm --filter contracts build", "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,css,scss,html}\"", "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,css,scss,html}\"", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a0d951..1d27ab4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,8 +43,11 @@ importers: specifier: 3.0.0-nightly.20251104 version: 3.0.0-nightly.20251104 '@noir-lang/noir_js': - specifier: 1.0.0-beta.15 - version: 1.0.0-beta.15 + specifier: 1.0.0-beta.16 + version: 1.0.0-beta.16 + '@radix-ui/react-accordion': + specifier: ^1.2.12 + version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-checkbox': specifier: ^1.3.3 version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -61,7 +64,7 @@ importers: specifier: ^2.2.6 version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-separator': - specifier: ^1.1.7 + specifier: ^1.1.8 version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-slot': specifier: ^1.2.4 @@ -69,6 +72,9 @@ importers: '@radix-ui/react-switch': specifier: ^1.2.6 version: 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-tabs': + specifier: ^1.1.13 + version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-tooltip': specifier: ^1.2.8 version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -102,6 +108,9 @@ importers: lucide-react: specifier: ^0.548.0 version: 0.548.0(react@19.2.0) + qrcode.react: + specifier: ^4.2.0 + version: 4.2.0(react@19.2.0) react: specifier: ^19.1.1 version: 19.2.0 @@ -120,6 +129,9 @@ importers: react-router-dom: specifier: ^7.9.4 version: 7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + recharts: + specifier: 2.15.4 + version: 2.15.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rehype-raw: specifier: ^7.0.0 version: 7.0.0 @@ -139,9 +151,27 @@ importers: specifier: ^4.1.16 version: 4.1.17 devDependencies: + '@chromatic-com/storybook': + specifier: ^5.0.0 + version: 5.0.0(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10)) '@eslint/js': specifier: ^9.36.0 version: 9.39.1 + '@storybook/addon-a11y': + specifier: ^10.1.11 + version: 10.1.11(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10)) + '@storybook/addon-docs': + specifier: ^10.1.11 + version: 10.1.11(@types/react@19.2.7)(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@storybook/addon-onboarding': + specifier: ^10.1.11 + version: 10.1.11(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10)) + '@storybook/addon-vitest': + specifier: ^10.1.11 + version: 10.1.11(@vitest/browser-playwright@4.0.16)(@vitest/browser@4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16))(@vitest/runner@4.0.16)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vitest@4.0.16) + '@storybook/react-vite': + specifier: ^10.1.11 + version: 10.1.11(esbuild@0.25.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) '@types/node': specifier: ^24.9.2 version: 24.10.1 @@ -154,6 +184,12 @@ importers: '@vitejs/plugin-react': specifier: ^5.0.4 version: 5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@vitest/browser-playwright': + specifier: ^4.0.16 + version: 4.0.16(bufferutil@4.0.9)(playwright@1.57.0)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + '@vitest/coverage-v8': + specifier: ^4.0.16 + version: 4.0.16(@vitest/browser@4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16))(vitest@4.0.16) axios: specifier: ^1.7.9 version: 1.13.2 @@ -166,12 +202,21 @@ importers: eslint-plugin-react-refresh: specifier: ^0.4.22 version: 0.4.24(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-storybook: + specifier: ^10.1.11 + version: 10.1.11(eslint@9.39.1(jiti@2.6.1))(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3) form-data: specifier: ^4.0.0 version: 4.0.5 globals: specifier: ^16.4.0 version: 16.5.0 + playwright: + specifier: ^1.57.0 + version: 1.57.0 + storybook: + specifier: ^10.1.11 + version: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) tsx: specifier: ^4.19.2 version: 4.20.6 @@ -190,6 +235,9 @@ importers: vite-plugin-node-polyfills: specifier: ^0.24.0 version: 0.24.0(rollup@4.53.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + vitest: + specifier: ^4.0.16 + version: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) contracts: dependencies: @@ -216,17 +264,17 @@ importers: specifier: ^0.87.8 version: 0.87.9 '@noir-lang/noir_js': - specifier: 1.0.0-beta.15 - version: 1.0.0-beta.15 + specifier: 1.0.0-beta.16 + version: 1.0.0-beta.16 '@nomicfoundation/hardhat-ignition': specifier: ^3.0.5 - version: 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@nomicfoundation/hardhat-ignition-ethers': specifier: ^3.0.5 - version: 3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-toolbox-mocha-ethers': specifier: ^3.0.1 - version: 3.0.1(6e08cdbcf3833ccb21ba5d746ad2a373) + version: 3.0.1(85850f878493c1930dc46a832d5f165d) '@openzeppelin/contracts': specifier: ^5.0.2 version: 5.4.0 @@ -264,8 +312,8 @@ importers: specifier: github:foundry-rs/forge-std#v1.9.4 version: https://codeload.github.com/foundry-rs/forge-std/tar.gz/1eea5bae12ae557d589f9f0f0edae2faa47cb262 hardhat: - specifier: ^3.0.13 - version: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + specifier: ^3.1.2 + version: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) mocha: specifier: ^11.7.5 version: 11.7.5 @@ -383,14 +431,48 @@ importers: specifier: 17.7.2 version: 17.7.2 + relayer: + dependencies: + cors: + specifier: ^2.8.5 + version: 2.8.5 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + ethers: + specifier: ^6.13.4 + version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + express: + specifier: 4.19.2 + version: 4.19.2 + shared: + specifier: workspace:* + version: link:../shared + devDependencies: + '@types/cors': + specifier: ^2.8.17 + version: 2.8.19 + '@types/express': + specifier: ^4.17.21 + version: 4.17.25 + '@types/node': + specifier: ^20.11.0 + version: 20.19.27 + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.3.3 + version: 5.9.3 + shared: dependencies: '@aztec/bb.js': specifier: 3.0.0-nightly.20251104 version: 3.0.0-nightly.20251104 '@noir-lang/noir_js': - specifier: 1.0.0-beta.15 - version: 1.0.0-beta.15 + specifier: 1.0.0-beta.16 + version: 1.0.0-beta.16 '@zkpassport/poseidon2': specifier: ^0.6.2 version: 0.6.2 @@ -413,6 +495,9 @@ importers: packages: + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@adraffy/ens-normalize@1.10.0': resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} @@ -505,6 +590,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -517,6 +606,16 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@chromatic-com/storybook@5.0.0': + resolution: {integrity: sha512-8wUsqL8kg6R5ue8XNE7Jv/iD1SuE4+6EXMIGIuE+T2loBITEACLfC3V8W44NJviCLusZRMWbzICddz0nU0bFaw==} + engines: {node: '>=20.0.0', yarn: '>=1.22.18'} + peerDependencies: + storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -904,10 +1003,27 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3': + resolution: {integrity: sha512-9TGZuAX+liGkNKkwuo3FYJu7gHWT0vkBcf7GkOe7s7fmC19XwH/4u5u7sDIFrMooe558ORcmuBvBz7Ur5PlbHw==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -931,6 +1047,12 @@ packages: resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} engines: {node: '>= 14.0.0'} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': ^19.1.16 + react: '>=16' + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} cpu: [arm64] @@ -961,6 +1083,9 @@ packages: cpu: [x64] os: [win32] + '@neoconfetti/react@1.0.0': + resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} + '@noble/ciphers@1.2.1': resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} engines: {node: ^14.21.3 || >=16} @@ -1010,53 +1135,56 @@ packages: resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} - '@noir-lang/acvm_js@1.0.0-beta.15': - resolution: {integrity: sha512-WQNMycnVGj0J369BDcsa0N6n0IlISqXEznzDBHiP2yugHgTAoxiDzXizRW10K6u/w0EOVrl+bybLxNxLIPUSYQ==} + '@noir-lang/acvm_js@1.0.0-beta.16': + resolution: {integrity: sha512-2xcEE0mCFaZEvVoKVVsG5DTUgj68duFosIvV0Z19Gn5YM1Ay5pHQnFBX4xfhJPA/0Ex8yMRZA/QDE4jpMz96KQ==} - '@noir-lang/noir_js@1.0.0-beta.15': - resolution: {integrity: sha512-ffN3rWzcqaO+FmBF6quFqgXhEK1gyJ8TQ9V4V3A+PIKYE94BOB0L84McxofbRqt3TFuSloBymGiFrJ/Gx8Q8eQ==} + '@noir-lang/noir_js@1.0.0-beta.16': + resolution: {integrity: sha512-DHgD73WVR6ly6c+5ocrLWLooppYwTsvx4pyndloXlXm8LcJ4ouySg4dNgN8hqNLrTixqxjWu8wBy7eYiAS1iHQ==} - '@noir-lang/noirc_abi@1.0.0-beta.15': - resolution: {integrity: sha512-ZJ5pUSKiZ6Nyj6DcXmLkf/+OA12cApYq/XPYePxX7v1Z2mLLl1/Gj8dO/greHUYRD47ziXIgyaZQWryE3+4ifw==} + '@noir-lang/noirc_abi@1.0.0-beta.16': + resolution: {integrity: sha512-4RpTEyw34ap65B7gQQLTeXoRtFACsATd+o4fgjLgvoIBiwwftcp2+MOFGJA3icRUJyBXknmlNu+HXCOI7Vl+Xg==} - '@noir-lang/types@1.0.0-beta.15': - resolution: {integrity: sha512-FCydHArW6+oOSCxSIsprOExDaBMmxh0a9+ZhXigxFDZF6j96wzy3WvA0XLgczZzAjWOiBPCr4voTW1bsM0Ca2A==} + '@noir-lang/types@1.0.0-beta.16': + resolution: {integrity: sha512-QDZRdvC3NZ1USCOkmcgONoerQl5eWpl2uPreE/BN+bidgz+Q3cANW/KO9tt0ZeWWVMfLrYV2n7o6l0y8pJUV1g==} - '@nomicfoundation/edr-darwin-arm64@0.12.0-next.14': - resolution: {integrity: sha512-sl0DibKSUOS7JXhUtaQ6FJUY+nk+uq5gx+Fyd9iiqs8awZPNn6KSuvV1EbWCi+yd3mrxgZ/wO8E77C1Dxj4xQA==} + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.21': + resolution: {integrity: sha512-WUBBIlhW9UcYhEKlpuG+A/9gQsTciWID+shi2p5iYzArIZAHssyuUGOZF+z5/KQTyAC+GRQd/2YvCQacNnpOIg==} engines: {node: '>= 20'} - '@nomicfoundation/edr-darwin-x64@0.12.0-next.14': - resolution: {integrity: sha512-lfmatc1MSOaw0rDFB+ynnAGz5TWm3hSeY/+zDpPZghMODZelXm4JCqF41CQ6paLsW3X/pXcHM1HUGCUBWeoI/A==} + '@nomicfoundation/edr-darwin-x64@0.12.0-next.21': + resolution: {integrity: sha512-DOLp9TS3pRxX5OVqH2SMv/hLmo2XZcciO+PLaoXcJGMTmUqDJbc1kOS7+e/kvf+f12e2Y4b/wPQGXKGRgcx61w==} engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.14': - resolution: {integrity: sha512-sWun3PhVgat8d4lg1d5MAXSIsFlSMBzvrpMSDFNOU9hPJEclSHbHBMRcarQuGqwm/5ZBzTwCS25u78A+UATTrg==} + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.21': + resolution: {integrity: sha512-yYLkOFA9Y51TdHrZIFM6rLzArw/iEQuIGwNnTRUXVBO1bNyKVxfaO7qg4WuRSNWKuZAtMawilcjoyHNuxzm/oQ==} engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.14': - resolution: {integrity: sha512-omWKioD8fFp7ayCeSDu2CqvG78+oYw8zdVECDwZVmE0jpszRCsTufNYflWRQnlGqH6GqjEUwq2c3yLxFgOTjFg==} + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.21': + resolution: {integrity: sha512-/L2hJYoUSHG9RTZRfOfYfsEBo1I30EQt3M+kWTDCS09jITnotWbqS9H/qbjd8u+8/xBBtAxNFhBgrIYu0GESSw==} engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.14': - resolution: {integrity: sha512-vk0s4SaC7s1wa98W24a4zqunTK/yIcSEnsSLRM/Nl+JJs6iqS8tvmnh/BbFINORMBJ065OWc10qw2Lsbu/rxtg==} + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.21': + resolution: {integrity: sha512-m5mjLjGbmiRwnv2UX48olr6NxTewt73i3f6pgqpTcQKgHxGWVvEHqDbhdhP2H8Qf31cyya/Qv9p6XQziPfjMYg==} engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.14': - resolution: {integrity: sha512-/xKQD6c2RXQBIb30iTeh/NrMdYvHs6Nd+2UXS6wxlfX7GzRPOkpVDiDGD7Sda82JI459KH67dADOD6CpX8cpHQ==} + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.21': + resolution: {integrity: sha512-FRGJwIPBC0UAtoWHd97bQ3OQwngp3vA4EjwZQqiicCapKoiI9BPt4+eyiZq2eq/K0+I0rHs25hw+dzU0QZL1xg==} engines: {node: '>= 20'} - '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.14': - resolution: {integrity: sha512-GZcyGdOoLWnUtfPU+6B1vUi4fwf3bouSRf3xuKFHz3p/WNhpDK+8Esq3UmOmYAZWRgFT0ZR6XUk9H2owGDTVvQ==} + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.21': + resolution: {integrity: sha512-rpH/iKqn0Dvbnj+o5tv3CtDNAsA9AnBNHNmEHoJPNnB5rhR7Zw1vVg2MaE1vzCvIONQGKGkArqC+dA7ftsOcpA==} engines: {node: '>= 20'} - '@nomicfoundation/edr@0.12.0-next.14': - resolution: {integrity: sha512-MGHY2x7JaNdkqlQxFBYoM7Miw2EqsQrI3ReVZMwLP5mULSRTAOnt3hCw6cnjXxGi991HnejNAedJofke6OdqqA==} + '@nomicfoundation/edr@0.12.0-next.21': + resolution: {integrity: sha512-j4DXqk/b2T1DK3L/YOZtTjwXqr/as4n+eKulu3KGVxyzOv2plZqTv9WpepQSejc0298tk/DBdMVwqzU3sd8CAA==} engines: {node: '>= 20'} '@nomicfoundation/hardhat-errors@3.0.5': resolution: {integrity: sha512-8Ayqf6hFM1glmrSxrXgX6n2pn5uTlHNxEB8N5Me0DOeOGB67PRIrQdiO+RzUhrNW5YgWUNWBevOLQbW06uQ79g==} + '@nomicfoundation/hardhat-errors@3.0.6': + resolution: {integrity: sha512-3x+OVdZv7Rgy3z6os9pB6kiHLxs6q0PCXHRu+WLZflr44PG9zW+7V9o+ehrUqmmivlHcIFr3Qh4M2wZVuoCYww==} + '@nomicfoundation/hardhat-ethers-chai-matchers@3.0.2': resolution: {integrity: sha512-nkg+z+fq5PXcRxS/zadyosAA+oPp3sdWrKpuOcASDf0RjqsN2LsNymML0VNNkZF8TF+hYa36fbV+QOas2Fm2BQ==} peerDependencies: @@ -1197,12 +1325,28 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} '@radix-ui/primitive@1.1.3': resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + peerDependencies: + '@types/react': ^19.1.16 + '@types/react-dom': ^19.1.9 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-arrow@1.1.7': resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: @@ -1229,6 +1373,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': ^19.1.16 + '@types/react-dom': ^19.1.9 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.1.7': resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: @@ -1500,6 +1657,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': ^19.1.16 + '@types/react-dom': ^19.1.9 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tooltip@1.2.8': resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} peerDependencies: @@ -1760,6 +1930,101 @@ packages: resolution: {integrity: sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==} engines: {node: '>=18'} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@storybook/addon-a11y@10.1.11': + resolution: {integrity: sha512-3sr6HmcDgW1+TQAV9QtWBE3HlGyfFXVZY3RECTNLNH6fRC+rYQCItisvQIVxQpyftLSQ8EAMN9JQzs495MjWNg==} + peerDependencies: + storybook: ^10.1.11 + + '@storybook/addon-docs@10.1.11': + resolution: {integrity: sha512-Jwm291Fhim2eVcZIVlkG1B2skb0ZI9oru6nqMbJxceQZlvZmcIa4oxvS1oaMTKw2DJnCv97gLm57P/YvRZ8eUg==} + peerDependencies: + storybook: ^10.1.11 + + '@storybook/addon-onboarding@10.1.11': + resolution: {integrity: sha512-DNJv0IDl5XBrY+PPgwnMXLyp3omPkMOS6xe8ejG3csT71B6+3VueL6m7Qivh6739SnAV0QBU5SQlpMA0gQUcSA==} + peerDependencies: + storybook: ^10.1.11 + + '@storybook/addon-vitest@10.1.11': + resolution: {integrity: sha512-YbZzeKO3v+Xr97/malT4DZIATkVZT5EHNYx3xzEfPVuk19dDETAVYXO+tzcqCQHsgdKQHkmd56vv8nN3J3/kvw==} + peerDependencies: + '@vitest/browser': ^3.0.0 || ^4.0.0 + '@vitest/browser-playwright': ^4.0.0 + '@vitest/runner': ^3.0.0 || ^4.0.0 + storybook: ^10.1.11 + vitest: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/runner': + optional: true + vitest: + optional: true + + '@storybook/builder-vite@10.1.11': + resolution: {integrity: sha512-MMD09Ap7FyzDfWG961pkIMv/w684XXe1bBEi+wCEpHxvrgAd3j3A9w/Rqp9Am2uRDPCEdi1QgSzS3SGW3aGThQ==} + peerDependencies: + storybook: ^10.1.11 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@storybook/csf-plugin@10.1.11': + resolution: {integrity: sha512-Ant0NhgqHKzQsseeVTSetZCuDHHs0W2HRkHt51Kg/sUl0T/sDtfVA+fWZT8nGzGZqYSFkxqYPWjauPmIhPtaRw==} + peerDependencies: + esbuild: '*' + rollup: '*' + storybook: ^10.1.11 + vite: '*' + webpack: '*' + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@2.0.1': + resolution: {integrity: sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@storybook/react-dom-shim@10.1.11': + resolution: {integrity: sha512-o8WPhRlZbORUWG9lAgDgJP0pi905VHJUFJr1Kp8980gHqtlemtnzjPxKy5vFwj6glNhAlK8SS8OOYzWP7hloTQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.11 + + '@storybook/react-vite@10.1.11': + resolution: {integrity: sha512-qh1BCD25nIoiDfqwha+qBkl7pcG4WuzM+c8tsE63YEm8AFIbNKg5K8lVUoclF+4CpFz7IwBpWe61YUTDfp+91w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.11 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@storybook/react@10.1.11': + resolution: {integrity: sha512-rmMGmEwBaM2YpB8oDk2moM0MNjNMqtwyoPPZxjyruY9WVhYca8EDPGKEdRzUlb4qZJsTgLi7VU4eqg6LD/mL3Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.11 + typescript: '>= 4.9.x' + peerDependenciesMeta: + typescript: + optional: true + '@streamparser/json-node@0.0.22': resolution: {integrity: sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==} @@ -1864,6 +2129,20 @@ packages: peerDependencies: react: ^18 || ^19 + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@tsconfig/node10@1.0.12': resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} @@ -1883,6 +2162,9 @@ packages: typechain: ^8.3.2 typescript: '>=4.7.0' + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1895,24 +2177,78 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + '@types/chai-as-promised@8.0.2': resolution: {integrity: sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==} '@types/chai@4.3.20': resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/express-serve-static-core@4.19.7': + resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1922,6 +2258,12 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/mocha@10.0.10': resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} @@ -1934,6 +2276,9 @@ packages: '@types/node@18.15.13': resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + '@types/node@20.19.27': + resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} + '@types/node@20.8.8': resolution: {integrity: sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==} @@ -1949,6 +2294,12 @@ packages: '@types/prettier@2.7.3': resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -1960,6 +2311,18 @@ packages: '@types/react@19.2.7': resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -2037,6 +2400,78 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitest/browser-playwright@4.0.16': + resolution: {integrity: sha512-I2Fy/ANdphi1yI46d15o0M1M4M0UJrUiVKkH5oKeRZZCdPg0fw/cfTKZzv9Ge9eobtJYp4BGblMzXdXH0vcl5g==} + peerDependencies: + playwright: '*' + vitest: 4.0.16 + + '@vitest/browser@4.0.16': + resolution: {integrity: sha512-t4toy8X/YTnjYEPoY0pbDBg3EvDPg1elCDrfc+VupPHwoN/5/FNQ8Z+xBYIaEnOE2vVEyKwqYBzZ9h9rJtZVcg==} + peerDependencies: + vitest: 4.0.16 + + '@vitest/coverage-v8@4.0.16': + resolution: {integrity: sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==} + peerDependencies: + '@vitest/browser': 4.0.16 + vitest: 4.0.16 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + + '@vitest/expect@4.0.16': + resolution: {integrity: sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==} + + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/mocker@4.0.16': + resolution: {integrity: sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/pretty-format@4.0.16': + resolution: {integrity: sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==} + + '@vitest/runner@4.0.16': + resolution: {integrity: sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==} + + '@vitest/snapshot@4.0.16': + resolution: {integrity: sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==} + + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + + '@vitest/spy@4.0.16': + resolution: {integrity: sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==} + + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@vitest/utils@4.0.16': + resolution: {integrity: sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==} + '@zkpassport/poseidon2@0.6.2': resolution: {integrity: sha512-6sFHX9kAcrmDmBEEndvjZ8DA9FomunirQ5oCV6oD7bqr/lP0n0OBSRn86SZgQBXwRR+vq7sk16y31OgRBIOJ5Q==} @@ -2127,6 +2562,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.3: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} @@ -2145,6 +2584,13 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} @@ -2173,6 +2619,13 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + ast-v8-to-istanbul@0.3.10: + resolution: {integrity: sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2192,6 +2645,10 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axe-core@4.11.0: + resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} + engines: {node: '>=4'} + axios@1.13.2: resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} @@ -2300,6 +2757,10 @@ packages: builtin-status-codes@3.0.0: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2363,6 +2824,10 @@ packages: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2402,6 +2867,18 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chromatic@13.3.4: + resolution: {integrity: sha512-TR5rvyH0ESXobBB3bV8jc87AEAFQC7/n+Eb4XWhJz6hW3YNxIQPVjcbgLv+a4oKHEl1dUBueWSoIQsOVGTd+RQ==} + hasBin: true + peerDependencies: + '@chromatic-com/cypress': ^0.*.* || ^1.0.0 + '@chromatic-com/playwright': ^0.*.* || ^1.0.0 + peerDependenciesMeta: + '@chromatic-com/cypress': + optional: true + '@chromatic-com/playwright': + optional: true + ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} @@ -2541,6 +3018,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} @@ -2564,9 +3045,56 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + date-fns@3.3.1: resolution: {integrity: sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==} @@ -2603,6 +3131,9 @@ packages: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + decode-named-character-reference@1.2.0: resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} @@ -2628,10 +3159,22 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.4.0: + resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -2698,6 +3241,19 @@ packages: diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + domain-browser@4.22.0: resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} engines: {node: '>=10'} @@ -2740,6 +3296,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -2795,6 +3355,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -2862,6 +3425,12 @@ packages: peerDependencies: eslint: '>=8.40' + eslint-plugin-storybook@10.1.11: + resolution: {integrity: sha512-mbq2r2kK5+AcLl0XDJ3to91JOgzCbHOqj+J3n+FRw6drk+M1boRqMShSoMMm0HdzXPLmlr7iur+qJ5ZuhH6ayQ==} + peerDependencies: + eslint: '>=8' + storybook: ^10.1.11 + eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2888,6 +3457,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -2906,6 +3480,9 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2929,6 +3506,9 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -2939,6 +3519,10 @@ packages: evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} @@ -2992,6 +3576,10 @@ packages: file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filesize@10.1.6: + resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} + engines: {node: '>= 10.4.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -3073,6 +3661,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -3123,6 +3716,11 @@ packages: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} deprecated: Glob versions prior to v9 are no longer supported @@ -3154,8 +3752,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - hardhat@3.0.15: - resolution: {integrity: sha512-cXxaeSxFJ+u0MfbvWsS3Gdr7/uP7wjo4xviYcGdu9AKtwY6YsU+v0quK/j1NWmvO1Y4gk350SdZzQw++hJy4LA==} + hardhat@3.1.2: + resolution: {integrity: sha512-ULD5dQEU2/eXh+D/bfgD7j0kV0ynFAGh+F77VNLsQ7MAMTbFEAJLchyubzzeNBTh4n2pu0CG3juECg9s9mjTuA==} hasBin: true has-flag@3.0.0: @@ -3226,6 +3824,9 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -3322,6 +3923,10 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -3374,7 +3979,12 @@ packages: resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} engines: {node: '>= 0.4'} - is-extglob@2.1.1: + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -3393,6 +4003,11 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-nan@1.3.2: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} @@ -3429,6 +4044,10 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -3452,9 +4071,29 @@ packages: peerDependencies: ws: '*' + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -3472,6 +4111,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -3513,6 +4155,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + keygrip@1.1.0: resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} engines: {node: '>= 0.6'} @@ -3686,6 +4331,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -3694,9 +4343,20 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magicast@0.5.1: + resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -3885,12 +4545,20 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3938,6 +4606,10 @@ packages: motion-utils@12.23.6: resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4021,6 +4693,9 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -4039,6 +4714,10 @@ packages: only@0.0.2: resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -4119,12 +4798,19 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} @@ -4178,10 +4864,28 @@ packages: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true + pixelmatch@7.1.0: + resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} + hasBin: true + pkg-dir@5.0.0: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} + playwright-core@1.57.0: + resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.57.0: + resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} + engines: {node: '>=18'} + hasBin: true + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -4212,6 +4916,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -4262,6 +4970,11 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qrcode.react@4.2.0: + resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} @@ -4301,6 +5014,15 @@ packages: react-devtools-core@4.28.5: resolution: {integrity: sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==} + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@8.0.2: + resolution: {integrity: sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==} + engines: {node: ^20.9.0 || >=22} + react-dom@19.2.0: resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: @@ -4323,6 +5045,12 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-markdown@10.1.0: resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} peerDependencies: @@ -4381,6 +5109,12 @@ packages: peerDependencies: react: ^16.3.0 || ^17.0.0 || ^18.0.0 + react-smooth@4.0.4: + resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-style-singleton@2.2.3: resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} engines: {node: '>=10'} @@ -4391,6 +5125,12 @@ packages: '@types/react': optional: true + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -4422,6 +5162,24 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + + recharts@2.15.4: + resolution: {integrity: sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==} + engines: {node: '>=14'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + reduce-flatten@2.0.0: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} engines: {node: '>=6'} @@ -4496,6 +5254,10 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -4597,6 +5359,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4604,6 +5369,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -4648,6 +5417,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -4660,6 +5432,18 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + storybook@10.1.11: + resolution: {integrity: sha512-pKP5jXJYM4OjvNklGuHKO53wOCAwfx79KvZyOWHoi9zXUH5WVMFUe/ZfWyxXG/GTcj0maRgHGUjq/0I43r0dDQ==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} @@ -4702,6 +5486,14 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -4766,10 +5558,32 @@ packages: resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} engines: {node: '>=0.6.0'} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + to-buffer@1.2.2: resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} @@ -4782,6 +5596,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + treeify@1.1.0: resolution: {integrity: sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==} engines: {node: '>=0.6'} @@ -4802,6 +5620,10 @@ packages: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + ts-essentials@7.0.3: resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} peerDependencies: @@ -4836,6 +5658,10 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} @@ -4962,10 +5788,18 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + update-browserslist-db@1.1.4: resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true @@ -4999,6 +5833,11 @@ packages: '@types/react': optional: true + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -5029,6 +5868,9 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + viem@2.21.0: resolution: {integrity: sha512-9g3Gw2nOU6t4bNuoDI5vwVExzIxseU0J7Jjx10gA2RNQVrytIrLxggW++tWEe3w4mnnm/pS1WgZFjQ/QKf/nHw==} peerDependencies: @@ -5090,6 +5932,40 @@ packages: yaml: optional: true + vitest@4.0.16: + resolution: {integrity: sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.16 + '@vitest/browser-preview': 4.0.16 + '@vitest/browser-webdriverio': 4.0.16 + '@vitest/ui': 4.0.16 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -5099,6 +5975,9 @@ packages: webauthn-p256@0.0.5: resolution: {integrity: sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} @@ -5108,6 +5987,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + widest-line@3.1.0: resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} engines: {node: '>=8'} @@ -5194,6 +6078,10 @@ packages: utf-8-validate: optional: true + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -5253,6 +6141,8 @@ packages: snapshots: + '@adobe/css-tools@4.4.4': {} + '@adraffy/ens-normalize@1.10.0': {} '@adraffy/ens-normalize@1.10.1': {} @@ -5393,6 +6283,8 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.28.4': {} + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -5416,6 +6308,20 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@bcoe/v8-coverage@1.0.2': {} + + '@chromatic-com/storybook@5.0.0(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))': + dependencies: + '@neoconfetti/react': 1.0.0 + chromatic: 13.3.4 + filesize: 10.1.6 + jsonfile: 6.2.0 + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + strip-ansi: 7.1.2 + transitivePeerDependencies: + - '@chromatic-com/cypress' + - '@chromatic-com/playwright' + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -5773,6 +6679,12 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -5782,6 +6694,14 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + glob: 11.1.0 + react-docgen-typescript: 2.4.0(typescript@5.9.3) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + optionalDependencies: + typescript: 5.9.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5810,6 +6730,12 @@ snapshots: dependencies: vary: 1.1.2 + '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.0)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.7 + react: 19.2.0 + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': optional: true @@ -5828,6 +6754,8 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true + '@neoconfetti/react@1.0.0': {} + '@noble/ciphers@1.2.1': {} '@noble/ciphers@1.3.0': {} @@ -5866,44 +6794,44 @@ snapshots: '@noble/hashes@1.8.0': {} - '@noir-lang/acvm_js@1.0.0-beta.15': {} + '@noir-lang/acvm_js@1.0.0-beta.16': {} - '@noir-lang/noir_js@1.0.0-beta.15': + '@noir-lang/noir_js@1.0.0-beta.16': dependencies: - '@noir-lang/acvm_js': 1.0.0-beta.15 - '@noir-lang/noirc_abi': 1.0.0-beta.15 - '@noir-lang/types': 1.0.0-beta.15 + '@noir-lang/acvm_js': 1.0.0-beta.16 + '@noir-lang/noirc_abi': 1.0.0-beta.16 + '@noir-lang/types': 1.0.0-beta.16 pako: 2.1.0 - '@noir-lang/noirc_abi@1.0.0-beta.15': + '@noir-lang/noirc_abi@1.0.0-beta.16': dependencies: - '@noir-lang/types': 1.0.0-beta.15 + '@noir-lang/types': 1.0.0-beta.16 - '@noir-lang/types@1.0.0-beta.15': {} + '@noir-lang/types@1.0.0-beta.16': {} - '@nomicfoundation/edr-darwin-arm64@0.12.0-next.14': {} + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.21': {} - '@nomicfoundation/edr-darwin-x64@0.12.0-next.14': {} + '@nomicfoundation/edr-darwin-x64@0.12.0-next.21': {} - '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.14': {} + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.21': {} - '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.14': {} + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.21': {} - '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.14': {} + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.21': {} - '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.14': {} + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.21': {} - '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.14': {} + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.21': {} - '@nomicfoundation/edr@0.12.0-next.14': + '@nomicfoundation/edr@0.12.0-next.21': dependencies: - '@nomicfoundation/edr-darwin-arm64': 0.12.0-next.14 - '@nomicfoundation/edr-darwin-x64': 0.12.0-next.14 - '@nomicfoundation/edr-linux-arm64-gnu': 0.12.0-next.14 - '@nomicfoundation/edr-linux-arm64-musl': 0.12.0-next.14 - '@nomicfoundation/edr-linux-x64-gnu': 0.12.0-next.14 - '@nomicfoundation/edr-linux-x64-musl': 0.12.0-next.14 - '@nomicfoundation/edr-win32-x64-msvc': 0.12.0-next.14 + '@nomicfoundation/edr-darwin-arm64': 0.12.0-next.21 + '@nomicfoundation/edr-darwin-x64': 0.12.0-next.21 + '@nomicfoundation/edr-linux-arm64-gnu': 0.12.0-next.21 + '@nomicfoundation/edr-linux-arm64-musl': 0.12.0-next.21 + '@nomicfoundation/edr-linux-x64-gnu': 0.12.0-next.21 + '@nomicfoundation/edr-linux-x64-musl': 0.12.0-next.21 + '@nomicfoundation/edr-win32-x64-msvc': 0.12.0-next.21 '@nomicfoundation/hardhat-errors@3.0.5': dependencies: @@ -5911,55 +6839,61 @@ snapshots: transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-ethers-chai-matchers@3.0.2(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(chai@5.3.3)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-errors@3.0.6': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 - '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-utils': 3.0.5 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/hardhat-ethers-chai-matchers@3.0.2(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(chai@5.3.3)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-errors': 3.0.6 + '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@nomicfoundation/hardhat-utils': 3.0.5 '@types/chai-as-promised': 8.0.2 chai: 5.3.3 chai-as-promised: 8.0.2(chai@5.3.3) deep-eql: 5.0.2 ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 debug: 4.4.3(supports-color@8.1.1) ethereum-cryptography: 2.2.1 ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@nomicfoundation/hardhat-ignition-ethers@3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-ignition-ethers@3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@nomicfoundation/hardhat-errors': 3.0.5 - '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-ignition': 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-ignition': 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/ignition-core': 3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@nomicfoundation/hardhat-errors': 3.0.5 '@nomicfoundation/hardhat-utils': 3.0.5 - '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/ignition-core': 3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nomicfoundation/ignition-ui': 3.0.5 chalk: 5.6.2 debug: 4.4.3(supports-color@8.1.1) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) json5: 2.2.3 prompts: 2.4.2 transitivePeerDependencies: @@ -5967,27 +6901,27 @@ snapshots: - supports-color - utf-8-validate - '@nomicfoundation/hardhat-keystore@3.0.3(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-keystore@3.0.3(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@noble/ciphers': 1.2.1 '@noble/hashes': 1.7.1 - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 '@nomicfoundation/hardhat-zod-utils': 3.0.1(zod@3.25.76) chalk: 5.6.2 debug: 4.4.3(supports-color@8.1.1) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: - supports-color '@nomicfoundation/hardhat-mocha@3.0.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 '@nomicfoundation/hardhat-zod-utils': 3.0.1(zod@3.25.76) chalk: 5.6.2 - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) mocha: 11.7.5 tsx: 4.20.6 zod: 3.25.76 @@ -5996,40 +6930,40 @@ snapshots: - supports-color - utf-8-validate - '@nomicfoundation/hardhat-network-helpers@3.0.3(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-network-helpers@3.0.3(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-toolbox-mocha-ethers@3.0.1(6e08cdbcf3833ccb21ba5d746ad2a373)': + '@nomicfoundation/hardhat-toolbox-mocha-ethers@3.0.1(85850f878493c1930dc46a832d5f165d)': dependencies: - '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-ethers-chai-matchers': 3.0.2(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(chai@5.3.3)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition': 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-ignition-ethers': 3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-keystore': 3.0.3(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-ethers-chai-matchers': 3.0.2(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(chai@5.3.3)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition': 3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-ignition-ethers': 3.0.5(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-ignition@3.0.5(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@nomicfoundation/ignition-core@3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-keystore': 3.0.3(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-mocha': 3.0.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-network-helpers': 3.0.3(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-typechain': 3.0.1(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3) - '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-network-helpers': 3.0.3(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-typechain': 3.0.1(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3) + '@nomicfoundation/hardhat-verify': 3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/ignition-core': 3.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) chai: 5.3.3 ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-typechain@3.0.1(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)': + '@nomicfoundation/hardhat-typechain@3.0.1(@nomicfoundation/hardhat-ethers@4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 - '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-errors': 3.0.6 + '@nomicfoundation/hardhat-ethers': 4.0.3(bufferutil@4.0.9)(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@nomicfoundation/hardhat-utils': 3.0.5 '@nomicfoundation/hardhat-zod-utils': 3.0.1(zod@3.25.76) '@typechain/ethers-v6': 0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3) debug: 4.4.3(supports-color@8.1.1) ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) typechain: 8.3.2(typescript@5.8.3) zod: 3.25.76 transitivePeerDependencies: @@ -6049,16 +6983,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-verify@3.0.7(hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@ethersproject/abi': 5.8.0 - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 '@nomicfoundation/hardhat-zod-utils': 3.0.1(zod@3.25.76) cbor2: 1.12.0 chalk: 5.6.2 debug: 4.4.3(supports-color@8.1.1) - hardhat: 3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) semver: 7.7.3 zod: 3.25.76 transitivePeerDependencies: @@ -6066,7 +7000,7 @@ snapshots: '@nomicfoundation/hardhat-zod-utils@3.0.1(zod@3.25.76)': dependencies: - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 zod: 3.25.76 transitivePeerDependencies: @@ -6137,10 +7071,29 @@ snapshots: '@pkgr/core@0.2.9': {} + '@polka/url@1.0.0-next.29': {} + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -6166,6 +7119,22 @@ snapshots: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.0) @@ -6445,6 +7414,22 @@ snapshots: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -6647,6 +7632,120 @@ snapshots: '@sentry/core@9.47.1': {} + '@standard-schema/spec@1.1.0': {} + + '@storybook/addon-a11y@10.1.11(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))': + dependencies: + '@storybook/global': 5.0.0 + axe-core: 4.11.0 + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + + '@storybook/addon-docs@10.1.11(@types/react@19.2.7)(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@19.2.0) + '@storybook/csf-plugin': 10.1.11(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@storybook/icons': 2.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@storybook/react-dom-shim': 10.1.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10)) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - esbuild + - rollup + - vite + - webpack + + '@storybook/addon-onboarding@10.1.11(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))': + dependencies: + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + + '@storybook/addon-vitest@10.1.11(@vitest/browser-playwright@4.0.16)(@vitest/browser@4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16))(@vitest/runner@4.0.16)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vitest@4.0.16)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + optionalDependencies: + '@vitest/browser': 4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + '@vitest/browser-playwright': 4.0.16(bufferutil@4.0.9)(playwright@1.57.0)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + '@vitest/runner': 4.0.16 + vitest: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + transitivePeerDependencies: + - react + - react-dom + + '@storybook/builder-vite@10.1.11(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@storybook/csf-plugin': 10.1.11(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@vitest/mocker': 3.2.4(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + ts-dedent: 2.2.0 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + transitivePeerDependencies: + - esbuild + - msw + - rollup + - webpack + + '@storybook/csf-plugin@10.1.11(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + unplugin: 2.3.11 + optionalDependencies: + esbuild: 0.25.12 + rollup: 4.53.3 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + + '@storybook/global@5.0.0': {} + + '@storybook/icons@2.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@storybook/react-dom-shim@10.1.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))': + dependencies: + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + + '@storybook/react-vite@10.1.11(esbuild@0.25.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + '@storybook/builder-vite': 10.1.11(esbuild@0.25.12)(rollup@4.53.3)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@storybook/react': 10.1.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3) + empathic: 2.0.0 + magic-string: 0.30.21 + react: 19.2.0 + react-docgen: 8.0.2 + react-dom: 19.2.0(react@19.2.0) + resolve: 1.22.11 + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + tsconfig-paths: 4.2.0 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + transitivePeerDependencies: + - esbuild + - msw + - rollup + - supports-color + - typescript + - webpack + + '@storybook/react@10.1.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/react-dom-shim': 10.1.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10)) + react: 19.2.0 + react-docgen: 8.0.2 + react-dom: 19.2.0(react@19.2.0) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@streamparser/json-node@0.0.22': dependencies: '@streamparser/json': 0.0.22 @@ -6728,6 +7827,30 @@ snapshots: '@tanstack/query-core': 5.90.11 react: 19.2.0 + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.28.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -6744,6 +7867,8 @@ snapshots: typechain: 8.3.2(typescript@5.8.3) typescript: 5.8.3 + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.5 @@ -6765,26 +7890,88 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.19.27 + '@types/chai-as-promised@8.0.2': dependencies: '@types/chai': 4.3.20 '@types/chai@4.3.20': {} + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.19.27 + + '@types/cors@2.8.19': + dependencies: + '@types/node': 20.19.27 + + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + '@types/debug@4.1.12': dependencies: '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} + + '@types/doctrine@0.0.9': {} + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 '@types/estree@1.0.8': {} + '@types/express-serve-static-core@4.19.7': + dependencies: + '@types/node': 20.19.27 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.7 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.10 + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 + '@types/http-errors@2.0.5': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': @@ -6794,6 +7981,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + '@types/mocha@10.0.10': {} '@types/mocha@10.0.6': {} @@ -6802,6 +7993,10 @@ snapshots: '@types/node@18.15.13': {} + '@types/node@20.19.27': + dependencies: + undici-types: 6.21.0 + '@types/node@20.8.8': dependencies: undici-types: 5.25.3 @@ -6820,6 +8015,10 @@ snapshots: '@types/prettier@2.7.3': {} + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + '@types/react-dom@19.2.3(@types/react@19.2.7)': dependencies: '@types/react': 19.2.7 @@ -6832,6 +8031,23 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/resolve@1.20.6': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.19.27 + + '@types/send@1.2.1': + dependencies: + '@types/node': 20.19.27 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 20.19.27 + '@types/send': 0.17.6 + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -6925,24 +8141,142 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.48.0': + '@typescript-eslint/visitor-keys@8.48.0': + dependencies: + '@typescript-eslint/types': 8.48.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-react@5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.47 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + + '@vitest/browser-playwright@4.0.16(bufferutil@4.0.9)(playwright@1.57.0)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16)': + dependencies: + '@vitest/browser': 4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + '@vitest/mocker': 4.0.16(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + playwright: 1.57.0 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/browser@4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16)': + dependencies: + '@vitest/mocker': 4.0.16(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@vitest/utils': 4.0.16 + magic-string: 0.30.21 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/coverage-v8@4.0.16(@vitest/browser@4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16))(vitest@4.0.16)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.0.16 + ast-v8-to-istanbul: 0.3.10 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + magicast: 0.5.1 + obug: 2.1.1 + std-env: 3.10.0 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + optionalDependencies: + '@vitest/browser': 4.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + '@vitest/expect@4.0.16': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@3.2.4(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + + '@vitest/mocker@4.0.16(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + dependencies: + '@vitest/spy': 4.0.16 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/pretty-format@4.0.16': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.16': + dependencies: + '@vitest/utils': 4.0.16 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.16': dependencies: - '@typescript-eslint/types': 8.48.0 - eslint-visitor-keys: 4.2.1 + '@vitest/pretty-format': 4.0.16 + magic-string: 0.30.21 + pathe: 2.0.3 - '@ungap/structured-clone@1.3.0': {} + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 - '@vitejs/plugin-react@5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))': + '@vitest/spy@4.0.16': {} + + '@vitest/utils@3.2.4': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.47 - '@types/babel__core': 7.20.5 - react-refresh: 0.18.0 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) - transitivePeerDependencies: - - supports-color + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@vitest/utils@4.0.16': + dependencies: + '@vitest/pretty-format': 4.0.16 + tinyrainbow: 3.0.3 '@zkpassport/poseidon2@0.6.2': {} @@ -7020,6 +8354,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansi-styles@6.2.3: {} anymatch@3.1.3: @@ -7035,6 +8371,12 @@ snapshots: dependencies: tslib: 2.8.1 + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + array-back@3.1.0: {} array-back@4.0.2: {} @@ -7061,6 +8403,16 @@ snapshots: assertion-error@2.0.1: {} + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + ast-v8-to-istanbul@0.3.10: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + astral-regex@2.0.0: {} asynckit@0.4.0: {} @@ -7073,6 +8425,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axe-core@4.11.0: {} + axios@1.13.2: dependencies: follow-redirects: 1.15.11 @@ -7218,6 +8572,10 @@ snapshots: builtin-status-codes@3.0.0: {} + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + bytes@3.1.2: {} c-kzg@4.0.0-alpha.1: @@ -7287,6 +8645,8 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chai@6.2.2: {} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -7330,6 +8690,8 @@ snapshots: dependencies: readdirp: 4.1.2 + chromatic@13.3.4: {} + ci-info@2.0.0: {} cipher-base@1.0.7: @@ -7458,6 +8820,11 @@ snapshots: core-util-is@1.0.3: {} + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + create-ecdh@4.0.4: dependencies: bn.js: 4.12.2 @@ -7505,8 +8872,48 @@ snapshots: crypto-js@4.2.0: {} + css.escape@1.5.1: {} + csstype@3.2.3: {} + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-ease@3.0.1: {} + + d3-format@3.1.0: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@3.1.0: {} + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + date-fns@3.3.1: {} dateformat@4.6.3: {} @@ -7529,6 +8936,8 @@ snapshots: decamelize@4.0.0: {} + decimal.js-light@2.5.1: {} + decode-named-character-reference@1.2.0: dependencies: character-entities: 2.0.2 @@ -7547,12 +8956,21 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.1: {} + + default-browser@5.4.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -7604,6 +9022,19 @@ snapshots: miller-rabin: 4.0.1 randombytes: 2.1.0 + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.28.4 + csstype: 3.2.3 + domain-browser@4.22.0: {} dotenv@16.4.5: {} @@ -7645,6 +9076,8 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.0: {} + encodeurl@1.0.2: {} end-of-stream@1.4.5: @@ -7727,6 +9160,8 @@ snapshots: es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -7800,6 +9235,15 @@ snapshots: dependencies: eslint: 9.39.1(jiti@2.6.1) + eslint-plugin-storybook@10.1.11(eslint@9.39.1(jiti@2.6.1))(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10))(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - supports-color + - typescript + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -7856,6 +9300,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -7870,6 +9316,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} etag@1.8.1: {} @@ -7909,6 +9359,8 @@ snapshots: event-target-shim@5.0.1: {} + eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} events@3.3.0: {} @@ -7918,6 +9370,8 @@ snapshots: md5.js: 1.3.5 safe-buffer: 5.2.1 + expect-type@1.3.0: {} + express@4.19.2: dependencies: accepts: 1.3.8 @@ -7989,6 +9443,8 @@ snapshots: file-uri-to-path@1.0.0: {} + filesize@10.1.6: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -8065,6 +9521,9 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -8119,6 +9578,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.1.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.1.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.1 + glob@7.1.7: dependencies: fs.realpath: 1.0.0 @@ -8155,10 +9623,10 @@ snapshots: graphemer@1.4.0: {} - hardhat@3.0.15(bufferutil@4.0.9)(utf-8-validate@5.0.10): + hardhat@3.1.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@nomicfoundation/edr': 0.12.0-next.14 - '@nomicfoundation/hardhat-errors': 3.0.5 + '@nomicfoundation/edr': 0.12.0-next.21 + '@nomicfoundation/hardhat-errors': 3.0.6 '@nomicfoundation/hardhat-utils': 3.0.5 '@nomicfoundation/hardhat-zod-utils': 3.0.1(zod@3.25.76) '@nomicfoundation/solidity-analyzer': 0.1.2 @@ -8304,6 +9772,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + html-escaper@2.0.2: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -8418,6 +9888,8 @@ snapshots: inline-style-parser@0.2.7: {} + internmap@2.0.3: {} + ipaddr.js@1.9.1: {} is-accessor-descriptor@1.0.1: @@ -8465,6 +9937,8 @@ snapshots: is-accessor-descriptor: 1.0.1 is-data-descriptor: 1.0.1 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -8483,6 +9957,10 @@ snapshots: is-hexadecimal@2.0.1: {} + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-nan@1.3.2: dependencies: call-bind: 1.0.8 @@ -8513,6 +9991,10 @@ snapshots: is-unicode-supported@0.1.0: {} + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isarray@2.0.5: {} @@ -8529,12 +10011,37 @@ snapshots: dependencies: ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + jiti@2.6.1: {} joycon@3.1.1: {} @@ -8545,6 +10052,8 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -8576,6 +10085,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + keygrip@1.1.0: dependencies: tsscmp: 1.0.6 @@ -8751,6 +10266,8 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.2.4: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -8759,10 +10276,22 @@ snapshots: dependencies: react: 19.2.0 + lz-string@1.5.0: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.5.1: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + make-error@1.3.6: {} markdown-table@3.0.4: {} @@ -9158,10 +10687,16 @@ snapshots: mimic-fn@2.1.0: {} + min-indent@1.0.1: {} + minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -9242,6 +10777,8 @@ snapshots: motion-utils@12.23.6: {} + mrmime@2.0.1: {} + ms@2.0.0: {} ms@2.1.2: {} @@ -9345,6 +10882,8 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 + obug@2.1.1: {} + on-exit-leak-free@2.1.2: {} on-finished@2.4.1: @@ -9361,6 +10900,13 @@ snapshots: only@0.0.2: {} + open@10.2.0: + dependencies: + default-browser: 5.4.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -9448,10 +10994,17 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.4 + minipass: 7.1.2 + path-to-regexp@0.1.7: {} path-to-regexp@6.3.0: {} + pathe@2.0.3: {} + pathval@1.1.1: {} pathval@2.0.1: {} @@ -9550,10 +11103,24 @@ snapshots: sonic-boom: 4.2.0 thread-stream: 3.1.0 + pixelmatch@7.1.0: + dependencies: + pngjs: 7.0.0 + pkg-dir@5.0.0: dependencies: find-up: 5.0.0 + playwright-core@1.57.0: {} + + playwright@1.57.0: + dependencies: + playwright-core: 1.57.0 + optionalDependencies: + fsevents: 2.3.2 + + pngjs@7.0.0: {} + possible-typed-array-names@1.1.0: {} postcss@8.5.6: @@ -9574,6 +11141,12 @@ snapshots: prettier@3.6.2: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + process-nextick-args@2.0.1: {} process-warning@2.3.2: {} @@ -9627,6 +11200,10 @@ snapshots: punycode@2.3.1: {} + qrcode.react@4.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + qs@6.11.0: dependencies: side-channel: 1.1.0 @@ -9674,6 +11251,25 @@ snapshots: - bufferutil - utf-8-validate + react-docgen-typescript@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + react-docgen@8.0.2: + dependencies: + '@babel/core': 7.28.5 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.11 + strip-indent: 4.1.1 + transitivePeerDependencies: + - supports-color + react-dom@19.2.0(react@18.2.0): dependencies: react: 18.2.0 @@ -9700,6 +11296,10 @@ snapshots: react-is@16.13.1: {} + react-is@17.0.2: {} + + react-is@18.3.1: {} + react-markdown@10.1.0(@types/react@19.2.7)(react@19.2.0): dependencies: '@types/hast': 3.0.4 @@ -9764,6 +11364,14 @@ snapshots: dependencies: react: 19.2.0 + react-smooth@4.0.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + fast-equals: 5.3.3 + prop-types: 15.8.1 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-transition-group: 4.4.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react-style-singleton@2.2.3(@types/react@19.2.7)(react@19.2.0): dependencies: get-nonce: 1.0.1 @@ -9772,6 +11380,15 @@ snapshots: optionalDependencies: '@types/react': 19.2.7 + react-transition-group@4.4.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + '@babel/runtime': 7.28.4 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react@18.2.0: dependencies: loose-envify: 1.4.0 @@ -9810,6 +11427,36 @@ snapshots: real-require@0.2.0: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recharts-scale@0.4.5: + dependencies: + decimal.js-light: 2.5.1 + + recharts@2.15.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + clsx: 2.1.1 + eventemitter3: 4.0.7 + lodash: 4.17.21 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-is: 18.3.1 + react-smooth: 4.0.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + recharts-scale: 0.4.5 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + reduce-flatten@2.0.0: {} rehype-raw@7.0.0: @@ -9917,6 +11564,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 + run-applescript@7.1.0: {} + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -10042,10 +11691,18 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + sisteransi@1.0.5: {} slice-ansi@3.0.0: @@ -10088,12 +11745,39 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + statuses@1.5.0: {} statuses@2.0.1: {} statuses@2.0.2: {} + std-env@3.10.0: {} + + storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(utf-8-validate@5.0.10): + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/expect': 3.2.4 + '@vitest/spy': 3.2.4 + esbuild: 0.25.12 + open: 10.2.0 + recast: 0.23.11 + semver: 7.7.3 + use-sync-external-store: 1.6.0(react@19.2.0) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + prettier: 3.6.2 + transitivePeerDependencies: + - '@testing-library/dom' + - bufferutil + - react + - react-dom + - utf-8-validate + stream-browserify@3.0.0: dependencies: inherits: 2.0.4 @@ -10143,8 +11827,13 @@ snapshots: dependencies: ansi-regex: 6.2.2 - strip-bom@3.0.0: - optional: true + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-indent@4.1.1: {} strip-json-comments@3.1.1: {} @@ -10209,11 +11898,23 @@ snapshots: dependencies: setimmediate: 1.0.5 + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@2.0.0: {} + + tinyrainbow@3.0.3: {} + + tinyspy@4.0.4: {} + to-buffer@1.2.2: dependencies: isarray: 2.0.5 @@ -10226,6 +11927,8 @@ snapshots: toidentifier@1.0.1: {} + totalist@3.0.1: {} + treeify@1.1.0: {} trim-lines@3.0.1: {} @@ -10243,6 +11946,8 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 + ts-dedent@2.2.0: {} + ts-essentials@7.0.3(typescript@5.8.3): dependencies: typescript: 5.8.3 @@ -10291,6 +11996,12 @@ snapshots: strip-bom: 3.0.0 optional: true + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@2.4.0: {} tslib@2.7.0: {} @@ -10417,8 +12128,17 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + unpipe@1.0.0: {} + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: browserslist: 4.28.0 @@ -10449,6 +12169,10 @@ snapshots: optionalDependencies: '@types/react': 19.2.7 + use-sync-external-store@1.6.0(react@19.2.0): + dependencies: + react: 19.2.0 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -10485,6 +12209,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + victory-vendor@36.9.2: + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + viem@2.21.0(bufferutil@4.0.9)(typescript@5.2.2)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.10.0 @@ -10561,6 +12302,45 @@ snapshots: lightningcss: 1.30.2 tsx: 4.20.6 + vitest@4.0.16(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6): + dependencies: + '@vitest/expect': 4.0.16 + '@vitest/mocker': 4.0.16(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6)) + '@vitest/pretty-format': 4.0.16 + '@vitest/runner': 4.0.16 + '@vitest/snapshot': 4.0.16 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 24.10.1 + '@vitest/browser-playwright': 4.0.16(bufferutil@4.0.9)(playwright@1.57.0)(utf-8-validate@5.0.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.6))(vitest@4.0.16) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + vm-browserify@1.1.2: {} web-namespaces@2.0.1: {} @@ -10570,6 +12350,8 @@ snapshots: '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 + webpack-virtual-modules@0.6.2: {} + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 @@ -10584,6 +12366,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + widest-line@3.1.0: dependencies: string-width: 4.2.3 @@ -10644,6 +12431,10 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + xtend@4.0.2: {} y18n@5.0.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 092765b..d9fa0a4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,3 +4,4 @@ packages: - "indexer/generated" - "contracts" - "shared" + - "relayer" diff --git a/relayer/.dockerignore b/relayer/.dockerignore new file mode 100644 index 0000000..e38c606 --- /dev/null +++ b/relayer/.dockerignore @@ -0,0 +1,43 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* +bun.lockb + +# Build outputs +dist +*.tsbuildinfo + +# Environment files (should be provided at runtime) +.env +.env.local +.env.*.local + +# Git +.git +.gitignore + +# IDE +.vscode +.idea +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Documentation +README.md +*.md + +# Docker +Dockerfile +.dockerignore +docker-compose.yml + +# Logs +logs +*.log diff --git a/relayer/.env.example b/relayer/.env.example new file mode 100644 index 0000000..d9875f9 --- /dev/null +++ b/relayer/.env.example @@ -0,0 +1,17 @@ +# Server Configuration +PORT=3000 +NODE_ENV=production + +# CORS Configuration +# Comma-separated list of allowed origins +ALLOWED_ORIGINS=https://commbank.eth.limo,http://localhost:3000,http://localhost:5173 + +# RPC Endpoints (with credentials hidden) +# Ethereum Mainnet +RPC_ETH_MAINNET=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY + +# Ethereum Sepolia Testnet +RPC_ETH_SEPOLIA=https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY + +# Optional: Enable RPC request logging (true/false) +LOG_RPC_REQUESTS=false diff --git a/relayer/Dockerfile b/relayer/Dockerfile new file mode 100644 index 0000000..cb1f4b2 --- /dev/null +++ b/relayer/Dockerfile @@ -0,0 +1,60 @@ +# Use official Node.js image as base +FROM node:20-alpine AS base +WORKDIR /app + +# Enable pnpm via corepack +RUN corepack enable && corepack prepare pnpm@10.16.1 --activate + +# Install dependencies - copy workspace files from monorepo root +FROM base AS deps +COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ +COPY relayer/package.json ./relayer/ +COPY shared/package.json ./shared/ +RUN pnpm install --filter relayer --filter shared + +# Build the application +FROM base AS builder +# Install esbuild globally for bundling +RUN npm install -g esbuild +COPY --from=deps /app/node_modules ./node_modules +COPY --from=deps /app/relayer/node_modules ./relayer/node_modules +COPY relayer ./relayer +COPY shared ./shared +WORKDIR /app/relayer +# Bundle to handle ESM module resolution (externalize npm packages, bundle local shared) +RUN esbuild src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js \ + --external:cors --external:express --external:ethers --external:dotenv + +# Production image +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 + +# Install curl for healthcheck +RUN apk add --no-cache curl + +# Copy workspace files for production install +COPY --from=deps /app/pnpm-lock.yaml /app/pnpm-workspace.yaml /app/package.json ./ +COPY --from=deps /app/relayer/package.json ./relayer/ +COPY --from=deps /app/shared/package.json ./shared/ + +# Install production dependencies only +RUN pnpm install --filter relayer --filter shared --prod --frozen-lockfile + +# Copy built application and shared package +COPY --from=builder /app/relayer/dist ./relayer/dist +COPY --from=builder /app/shared ./shared + +WORKDIR /app/relayer + +# Expose the port +EXPOSE 3000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3000/health || exit 1 + +# Run the application +CMD ["node", "./dist/index.js"] diff --git a/relayer/README.md b/relayer/README.md new file mode 100644 index 0000000..817f5e2 --- /dev/null +++ b/relayer/README.md @@ -0,0 +1,170 @@ +# CommBank.eth Relayer + +Transaction relayer and RPC proxy for CommBank.eth, providing private transaction relay and secure RPC endpoint access with CORS protection. + +## Features + +- **Transaction Relay**: Allows for submitting of transactions for a gasless UX +- **RPC Proxy**: Hide RPC credentials and enforce CORS policy + +## Quick Start + +### Development + +```bash +# Install dependencies +pnpm install + +# Copy environment configuration +cp .env.example .env + +# Edit .env with your RPC URLs and allowed origins + +# Run in development mode (with hot reload) +pnpm run dev + +# Or build and run in production mode +pnpm run build +pnpm run start +``` + +### Docker Deployment + +```bash +# From root +docker build -t commbank-eth-relayer -f relayer/Dockerfile . + +# Run the container +docker run -p 3000:3000 commbank-eth-relayer +``` + +## Configuration + +### Environment Variables + +Create a `.env` file based on `.env.example`: + +```bash +# Server Configuration +PORT=3000 +NODE_ENV=production + +# CORS Configuration +ALLOWED_ORIGINS=https://commbank.eth.limo,http://localhost:3000,http://localhost:5173 + +# RPC Endpoints +RPC_ETH_MAINNET=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY +RPC_ETH_SEPOLIA=https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY + +# Optional: Enable RPC request logging +LOG_RPC_REQUESTS=false +``` + +### Supported Chain IDs + +| Chain ID | Network | Environment Variable | +| -------- | ---------------- | -------------------- | +| 1 | Ethereum Mainnet | `RPC_ETH_MAINNET` | +| 11155111 | Ethereum Sepolia | `RPC_ETH_SEPOLIA` | + +## API Endpoints + +### Health Check + +```bash +GET /health +``` + +Response: + +```json +{ + "status": "ok", + "timestamp": "2024-01-12T10:30:00.000Z" +} +``` + +### RPC Proxy + +```bash +POST /rpc/:chainId +``` + +Forward JSON-RPC requests to the configured RPC endpoint for the specified chain. + +**Example: Get latest block on Ethereum Mainnet** + +```bash +curl -X POST http://localhost:3000/rpc/1 \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "eth_blockNumber", + "params": [], + "id": 1 + }' +``` + +### Transaction Relay + +```bash +POST /tx +``` + +Submit a zero-knowledge proof transaction for relay. + +**Request Body:** + +```json +{ + "proof": { + "proof": "0x...", + "publicInputs": ["0x...", "0x..."] + }, + "payload": ["0x..."] +} +``` + +**Response:** + +```json +{ + "success": true, + "message": "Transaction received and queued for processing", + "txId": "tx_1234567890_abc123" +} +``` + +## CORS Security + +The relayer enforces CORS to prevent unauthorized access to your RPC endpoints. + +**Configuration:** + +Set allowed origins in `.env`: + +```bash +ALLOWED_ORIGINS=https://commbank.eth.limo,https://app.example.com +``` + +**Behavior:** + +- Requests from allowed origins are permitted +- Requests with no origin (curl, mobile apps) are allowed +- Requests from unauthorized origins are blocked with CORS error + +**Testing CORS:** + +```bash +# Allowed origin - will succeed +curl -X POST http://localhost:3000/rpc/1 \ + -H "Origin: https://commbank.eth.limo" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' + +# Unauthorized origin - will fail +curl -X POST http://localhost:3000/rpc/1 \ + -H "Origin: https://malicious-site.com" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' +``` diff --git a/relayer/package.json b/relayer/package.json new file mode 100644 index 0000000..1eba1a8 --- /dev/null +++ b/relayer/package.json @@ -0,0 +1,29 @@ +{ + "name": "relayer", + "version": "1.0.0", + "description": "Transaction relayer for commbank.eth", + "main": "dist/index.js", + "scripts": { + "dev": "tsx watch src/index.ts", + "start": "node dist/index.js", + "build": "tsc" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.16.1", + "dependencies": { + "cors": "^2.8.5", + "dotenv": "^17.2.3", + "ethers": "^6.13.4", + "express": "4.19.2", + "shared": "workspace:*" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/express": "^4.17.21", + "@types/node": "^20.11.0", + "tsx": "^4.19.2", + "typescript": "^5.3.3" + } +} diff --git a/relayer/src/constants.ts b/relayer/src/constants.ts new file mode 100644 index 0000000..9d1d557 --- /dev/null +++ b/relayer/src/constants.ts @@ -0,0 +1,6 @@ +// RPC URL configuration - map chain IDs to RPC URLs +export const RPC_URLS: Record = { + "1": process.env.RPC_ETH_MAINNET || "", + "11155111": process.env.RPC_ETH_SEPOLIA || "", + "421614": process.env.RPC_ARB_SEPOLIA || "", +}; diff --git a/relayer/src/helpers.ts b/relayer/src/helpers.ts new file mode 100644 index 0000000..7003a14 --- /dev/null +++ b/relayer/src/helpers.ts @@ -0,0 +1,180 @@ +import { ethers, parseUnits } from "ethers"; +import { commbankDotEthAbi } from "shared/constants/abi/commbankdoteth"; +import { SUPPORTED_NETWORKS } from "shared/constants/networks"; +import { RPC_URLS } from "./constants"; +import type { QueuedTransaction, TxStatus } from "./types"; + +// Transaction queue and lookup map +export const transactionQueue: QueuedTransaction[] = []; +export const transactionMap: Map = new Map(); +let isProcessingQueue = false; + +/** + * Generate a unique transaction ID + */ +export function generateTxId(): string { + return `tx_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`; +} + +/** + * Get adjusted gas price from provider. + * Doubles the gas price to ensure transaction inclusion. + * Falls back to 2 gwei if gas price is unavailable. + */ +export async function getDoubledGasPrice( + provider: ethers.JsonRpcProvider, +): Promise { + const feeData = await provider.getFeeData(); + + // Use maxFeePerGas (EIP-1559) or gasPrice (legacy), with 2x multiplier + const basePrice = feeData.maxFeePerGas ?? feeData.gasPrice; + + if (!basePrice) { + // Fallback to 2 gwei if provider returns nothing + return parseUnits("2", "gwei"); + } + + // Double the gas price + return basePrice * 2n; +} + +/** + * Update transaction status and notify + */ +export function updateTxStatus( + txId: string, + status: TxStatus, + updates: Partial = {}, +): void { + const tx = transactionMap.get(txId); + if (tx) { + tx.status = status; + tx.updatedAt = Date.now(); + Object.assign(tx, updates); + console.log(` [tx] Transaction ${txId} status: ${status}`); + } +} + +/** + * Process a single transaction from the queue + */ +async function processTransaction(queuedTx: QueuedTransaction): Promise { + const { txId, request } = queuedTx; + + console.log(`\n[queue] Processing transaction ${txId}...`); + updateTxStatus(txId, "processing"); + + try { + // Get RPC URL for chain + const rpcUrl = RPC_URLS[String(request.chainId)]; + if (!rpcUrl) { + throw new Error(`RPC not configured for chain ${request.chainId}`); + } + + // Get sponsor private key + const sponsorPrivateKey = process.env.SPONSOR_PRIVATE_KEY; + if (!sponsorPrivateKey) { + throw new Error("SPONSOR_PRIVATE_KEY not configured"); + } + + // Get contract address + const contractAddress = SUPPORTED_NETWORKS[request.chainId].rpc; + if (!contractAddress) { + throw new Error(`Contract not configured for chain ${request.chainId}`); + } + + console.log(" - Type:", request.type); + console.log(" - Chain ID:", request.chainId); + + // Set up provider and signer + const provider = new ethers.JsonRpcProvider(rpcUrl); + const wallet = new ethers.Wallet(sponsorPrivateKey, provider); + + // Get doubled gas price + const gasPrice = await getDoubledGasPrice(provider); + console.log( + " - Gas price (2x):", + ethers.formatUnits(gasPrice, "gwei"), + "gwei", + ); + + // Initialize contract + const contract = new ethers.Contract( + contractAddress, + commbankDotEthAbi, + wallet, + ); + + // Submit transaction + let tx: ethers.ContractTransactionResponse; + + if (request.type === "transfer") { + tx = await contract.transfer( + request.proof, + request.publicInputs, + request.payload, + { gasPrice }, + ); + } else { + tx = await contract.transferExternal( + request.proof, + request.publicInputs, + request.payload, + { gasPrice }, + ); + } + + console.log(" [ok] Transaction submitted:", tx.hash); + updateTxStatus(txId, "submitted", { transactionHash: tx.hash }); + + // Wait for confirmation in background (don't block queue) + tx.wait() + .then(() => { + console.log(` [ok] Transaction ${txId} confirmed`); + updateTxStatus(txId, "confirmed"); + }) + .catch((error) => { + console.error( + ` [error] Transaction ${txId} failed on-chain:`, + error.message, + ); + updateTxStatus(txId, "failed", { + errorMessage: + error instanceof Error ? error.message : "Transaction reverted", + }); + }); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; + console.error(` [error] Transaction ${txId} failed:`, errorMessage); + updateTxStatus(txId, "failed", { errorMessage }); + } +} + +/** + * Process the transaction queue sequentially + */ +export async function processQueue(): Promise { + if (isProcessingQueue) { + return; + } + + isProcessingQueue = true; + + while (transactionQueue.length > 0) { + const queuedTx = transactionQueue[0]; + + // Update queue positions for all waiting transactions + transactionQueue.forEach((tx, index) => { + tx.queuePosition = index; + }); + + // Process the first transaction + await processTransaction(queuedTx); + + // Remove from queue after processing (regardless of success/failure) + transactionQueue.shift(); + } + + isProcessingQueue = false; +} diff --git a/relayer/src/index.ts b/relayer/src/index.ts new file mode 100644 index 0000000..2b238dc --- /dev/null +++ b/relayer/src/index.ts @@ -0,0 +1,331 @@ +import cors from "cors"; +import express, { Request, Response } from "express"; + +import "dotenv/config"; + +import { SUPPORTED_NETWORKS } from "shared/constants/networks"; +import { RPC_URLS } from "./constants"; +import { + generateTxId, + processQueue, + transactionMap, + transactionQueue, +} from "./helpers"; +import type { + QueuedTransaction, + SponsorRequest, + TransactionRequest, +} from "./types"; + +const app = express(); +const PORT = process.env.PORT || 3000; + +// CORS configuration - restrict to allowed origins +const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS + ? process.env.ALLOWED_ORIGINS.split(",") + : ["http://localhost:3000", "http://localhost:5173"]; + +app.use( + cors({ + origin: (origin, callback) => { + // Allow requests with no origin (like mobile apps or curl requests) + if (!origin) return callback(null, true); + + if (ALLOWED_ORIGINS.includes(origin)) { + callback(null, true); + } else { + callback(new Error("Not allowed by CORS")); + } + }, + credentials: true, + }), +); + +// Middleware to parse JSON bodies +app.use(express.json({ limit: "10mb" })); + +// Health check endpoint +app.get("/health", (_req: Request, res: Response) => { + res.json({ status: "ok", timestamp: new Date().toISOString() }); +}); + +// RPC proxy endpoint - forwards RPC requests to hide credentials +app.post("/rpc/:chainId", async (req: Request, res: Response) => { + try { + const { chainId } = req.params; + + // Validate chain ID + if (!RPC_URLS[chainId]) { + res.status(400).json({ + error: "Unsupported chain ID", + supportedChains: Object.keys(RPC_URLS), + }); + return; + } + + const rpcUrl = RPC_URLS[chainId]; + + if (!rpcUrl) { + res.status(503).json({ + error: "RPC endpoint not configured for this chain", + chainId, + }); + return; + } + + // Forward the JSON-RPC request + const response = await fetch(rpcUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(req.body), + }); + + const data = await response.json(); + + // Log RPC requests (optional, can be disabled in production) + if (process.env.LOG_RPC_REQUESTS === "true") { + console.log(`\n[rpc] Request to chain ${chainId}:`); + console.log(" Method:", req.body.method); + console.log(" Response status:", response.status); + } + + res.status(response.status).json(data); + } catch (error) { + console.error("Error proxying RPC request:", error); + res.status(500).json({ + error: "Failed to proxy RPC request", + message: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +// Main transaction endpoint +app.post("/tx", (req: Request, res: Response) => { + try { + const txRequest = req.body as TransactionRequest; + + // Validate the request structure + if (!txRequest.proof || !txRequest.payload) { + res.status(400).json({ + error: "Invalid request: missing proof or payload", + }); + return; + } + + if (!txRequest.proof.proof || !txRequest.proof.publicInputs) { + res.status(400).json({ + error: "Invalid proof structure: missing proof or publicInputs", + }); + return; + } + + // Log the received transaction + console.log("\n[tx] Received transaction request:"); + console.log(" - Proof length:", txRequest.proof.proof.length, "bytes"); + console.log(" - Public inputs:", txRequest.proof.publicInputs.length); + console.log(" - Payload items:", txRequest.payload.length); + + // Log public inputs + console.log("\n Public Inputs:"); + txRequest.proof.publicInputs.forEach((input, i) => { + console.log(` [${i}]: ${input.slice(0, 20)}...${input.slice(-10)}`); + }); + + // Log payload sizes + console.log("\n Payload sizes:"); + txRequest.payload.forEach((p, i) => { + console.log(` [${i}]: ${p.length} chars`); + }); + + // TODO: Add actual proof verification and transaction submission logic here + // For now, we just acknowledge receipt + + console.log("\n[ok] Transaction accepted for processing\n"); + + res.json({ + success: true, + message: "Transaction received and queued for processing", + txId: `tx_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`, + }); + } catch (error) { + console.error("Error processing transaction:", error); + res.status(500).json({ + error: "Internal server error", + message: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +// Sponsor transaction endpoint - queues transfer/transferExternal for submission +app.post("/tx/sponsor", (req: Request, res: Response) => { + try { + const sponsorRequest = req.body as SponsorRequest; + + // Validate request structure + if (!sponsorRequest.type || !sponsorRequest.chainId) { + res.status(400).json({ + error: "Invalid request: missing type or chainId", + }); + return; + } + + if (!["transfer", "transferExternal"].includes(sponsorRequest.type)) { + res.status(400).json({ + error: "Invalid type: must be 'transfer' or 'transferExternal'", + }); + return; + } + + if (!sponsorRequest.proof || !sponsorRequest.publicInputs) { + res.status(400).json({ + error: "Invalid request: missing proof or publicInputs", + }); + return; + } + + if (!sponsorRequest.payload || !Array.isArray(sponsorRequest.payload)) { + res.status(400).json({ + error: "Invalid request: missing or invalid payload", + }); + return; + } + + // Validate chain ID + const contractAddress = + SUPPORTED_NETWORKS[sponsorRequest.chainId].CommBankDotEth; + if (!contractAddress) { + res.status(400).json({ + error: "Unsupported chain ID", + supportedChains: Object.keys(SUPPORTED_NETWORKS), + }); + return; + } + + // Get RPC URL for chain + const rpcUrl = RPC_URLS[String(sponsorRequest.chainId)]; + if (!rpcUrl) { + res.status(400).json({ + error: "RPC not configured for this chain", + chainId: sponsorRequest.chainId, + }); + return; + } + + // Check sponsor is configured + if (!process.env.SPONSOR_PRIVATE_KEY) { + console.error("SPONSOR_PRIVATE_KEY not configured"); + res.status(500).json({ + error: "Sponsor not configured", + }); + return; + } + + // Generate transaction ID and create queued transaction + const txId = generateTxId(); + const now = Date.now(); + + const queuedTx: QueuedTransaction = { + txId, + status: "queued", + request: sponsorRequest, + createdAt: now, + updatedAt: now, + queuePosition: transactionQueue.length, + }; + + // Add to queue and lookup map + transactionQueue.push(queuedTx); + transactionMap.set(txId, queuedTx); + + console.log(`\n[sponsor] Transaction ${txId} queued`); + console.log(" - Type:", sponsorRequest.type); + console.log(" - Chain ID:", sponsorRequest.chainId); + console.log(" - Queue position:", queuedTx.queuePosition); + console.log(" - Queue length:", transactionQueue.length); + + // Start processing queue (non-blocking) + processQueue(); + + // Return immediately with txId + res.json({ + success: true, + txId, + status: "queued", + queuePosition: queuedTx.queuePosition, + }); + } catch (error) { + console.error("Error queuing transaction:", error); + + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; + + res.status(400).json({ + error: "Failed to queue transaction", + message: errorMessage, + }); + } +}); + +// Get transaction status by txId +app.get("/tx/sponsor/:txId", (req: Request, res: Response) => { + try { + const { txId } = req.params; + + const queuedTx = transactionMap.get(txId); + + if (!queuedTx) { + res.status(404).json({ + error: "Transaction not found", + txId, + }); + return; + } + + // Calculate current queue position if still queued + let queuePosition: number | undefined; + if (queuedTx.status === "queued") { + queuePosition = transactionQueue.findIndex((tx) => tx.txId === txId); + if (queuePosition === -1) queuePosition = undefined; + } + + res.json({ + txId: queuedTx.txId, + status: queuedTx.status, + transactionHash: queuedTx.transactionHash, + errorMessage: queuedTx.errorMessage, + queuePosition, + createdAt: queuedTx.createdAt, + updatedAt: queuedTx.updatedAt, + }); + } catch (error) { + console.error("Error getting transaction status:", error); + + res.status(500).json({ + error: "Failed to get transaction status", + message: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +// Start the server +app.listen(PORT, () => { + console.log(`\n[server] Relayer running on http://localhost:${PORT}`); + console.log(` POST /tx - Submit a transaction`); + console.log( + ` POST /tx/sponsor - Queue a sponsored transfer/withdraw transaction`, + ); + console.log(` GET /tx/sponsor/:txId - Get transaction status`); + console.log(` POST /rpc/:chainId - RPC proxy endpoint`); + console.log(` GET /health - Health check`); + console.log(`\n[cors] Allowed origins: ${ALLOWED_ORIGINS.join(", ")}`); + console.log( + `[rpc] Chains configured: ${Object.keys(RPC_URLS) + .filter((k) => RPC_URLS[k]) + .join(", ")}`, + ); + console.log( + `[sponsor] Chains configured: ${Object.keys(SUPPORTED_NETWORKS).join(", ")}\n`, + ); +}); diff --git a/relayer/src/types.ts b/relayer/src/types.ts new file mode 100644 index 0000000..5130ff8 --- /dev/null +++ b/relayer/src/types.ts @@ -0,0 +1,38 @@ +// Types for the proof structure +export interface ProofData { + proof: string; + publicInputs: string[]; +} + +export interface TransactionRequest { + proof: ProofData; + payload: string[]; +} + +// Sponsor transaction request type +export interface SponsorRequest { + type: "transfer" | "transferExternal"; + chainId: number; + proof: string; + publicInputs: string[]; + payload: string[]; +} + +// Transaction status types +export type TxStatus = + | "queued" + | "processing" + | "submitted" + | "confirmed" + | "failed"; + +export interface QueuedTransaction { + txId: string; + status: TxStatus; + request: SponsorRequest; + createdAt: number; + updatedAt: number; + transactionHash?: string; + errorMessage?: string; + queuePosition?: number; +} diff --git a/relayer/tsconfig.json b/relayer/tsconfig.json new file mode 100644 index 0000000..83e9234 --- /dev/null +++ b/relayer/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/shared/classes/TransferExternal.ts b/shared/classes/TransferExternal.ts new file mode 100644 index 0000000..96cc758 --- /dev/null +++ b/shared/classes/TransferExternal.ts @@ -0,0 +1,17 @@ +import { UltraHonkBackend } from "@aztec/bb.js"; +import { Noir } from "@noir-lang/noir_js"; + +import transferExternalCircuit from "../../circuits/transfer_external/target/transfer_external.json"; + +export class TransferExternal { + public transferExternalNoir: Noir; + public transferExternalBackend: UltraHonkBackend; + + constructor() { + // @ts-expect-error - not sure + this.transferExternalNoir = new Noir(transferExternalCircuit); + this.transferExternalBackend = new UltraHonkBackend( + transferExternalCircuit.bytecode, + ); + } +} diff --git a/shared/constants/abi/commbankdoteth.ts b/shared/constants/abi/commbankdoteth.ts index 47ed766..fc22e44 100644 --- a/shared/constants/abi/commbankdoteth.ts +++ b/shared/constants/abi/commbankdoteth.ts @@ -16,6 +16,11 @@ export const commbankDotEthAbi = [ name: "_withdrawalVerifier", type: "address", }, + { + internalType: "address", + name: "_transferExternalVerifier", + type: "address", + }, ], stateMutability: "nonpayable", type: "constructor", @@ -334,6 +339,19 @@ export const commbankDotEthAbi = [ stateMutability: "payable", type: "function", }, + { + inputs: [], + name: "depositVerifier", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -625,6 +643,55 @@ export const commbankDotEthAbi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "bytes", + name: "_proof", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_publicInputs", + type: "bytes32[]", + }, + { + internalType: "bytes[]", + name: "_payload", + type: "bytes[]", + }, + ], + name: "transferExternal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "transferExternalVerifier", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "transferVerifier", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -643,6 +710,19 @@ export const commbankDotEthAbi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "withdrawVerifier", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { diff --git a/shared/constants/networks.ts b/shared/constants/networks.ts new file mode 100644 index 0000000..aaeb530 --- /dev/null +++ b/shared/constants/networks.ts @@ -0,0 +1,26 @@ +interface NetworkConfig { + rpc: string; + CommBankDotEth: string; + name: string; +} + +export const SUPPORTED_NETWORKS: Record = { + // SEPOLIA + 11155111: { + rpc: "https://relayer-production-91b9.up.railway.app/rpc/11155111", + CommBankDotEth: "0x3b4eEb695754F868DF6BaF0c0B788cC6E553DbdA", + name: "Ethereum", + }, + // ARB SEPOLIA + 421614: { + rpc: "https://relayer-production-91b9.up.railway.app/rpc/421614", + CommBankDotEth: "0xC0e0C9DC1DE67B7f6434FfdDf2A33300ed6f49E3", + name: "Arb Sepolia", + }, + // MAINNET + 1: { + rpc: "https://relayer-production-91b9.up.railway.app/rpc/1", + name: "Ethereum", + CommBankDotEth: "0x5eEAAE6dA50C2cBC94F8A0B25a1D9bAD8225db1e", + }, +}; diff --git a/shared/constants/token.ts b/shared/constants/token.ts index 0231854..d396acf 100644 --- a/shared/constants/token.ts +++ b/shared/constants/token.ts @@ -7,6 +7,7 @@ export interface SupportedAsset { decimals: number; isNative?: boolean; roundTo?: number; + logo: string; } export const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; @@ -19,6 +20,17 @@ export const mainnetAssets: SupportedAsset[] = [ symbol: "AUDD", address: "0x4cCe605eD955295432958d8951D0B176C10720d5", decimals: 6, + logo: "audd-logo.png", + }, + { + chainId: 1, + lzEndpointId: 30101, + name: "USD Coin", + symbol: "USDC", + address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + decimals: 6, + roundTo: 2, + logo: "usdc-logo.png", }, { chainId: 1, @@ -28,7 +40,8 @@ export const mainnetAssets: SupportedAsset[] = [ address: ETH_ADDRESS, decimals: 18, isNative: true, - roundTo: 8, + roundTo: 5, + logo: "usdc-logo.png", }, ]; @@ -41,6 +54,7 @@ export const sepoliaAssets: SupportedAsset[] = [ address: "0x237eEeE66266c72DBb7Ee2Aa84811666cE4EB815", decimals: 6, roundTo: 2, + logo: "usdc-logo.png", }, { chainId: 11155111, @@ -50,6 +64,7 @@ export const sepoliaAssets: SupportedAsset[] = [ address: "0xd794125Bc226895b987845Ef768B8C104fAbecD5", decimals: 6, roundTo: 2, + logo: "audd-logo.png", }, { chainId: 11155111, @@ -59,18 +74,53 @@ export const sepoliaAssets: SupportedAsset[] = [ address: ETH_ADDRESS, decimals: 18, isNative: true, - roundTo: 8, + roundTo: 5, + logo: "eth-logo.png", + }, +]; + +export const arbSepoliaAssets: SupportedAsset[] = [ + { + chainId: 421614, + lzEndpointId: 40231, + name: "Australian Dollar Coin", + symbol: "AUDD", + address: "0xA09599efa9a31036D20a9eEF07C69E77937E784E", + decimals: 6, + roundTo: 2, + logo: "audd-logo.png", + }, + { + chainId: 421614, + lzEndpointId: 40231, + name: "USD Coin", + symbol: "USDC", + address: "0xD1CAD1C8CEEdeD7Ad65440fd643E2d9320c2bf51", + decimals: 6, + roundTo: 2, + logo: "usdc-logo.png", + }, + { + chainId: 421614, + lzEndpointId: 40231, + name: "Ethereum", + symbol: "ETH", + address: ETH_ADDRESS, + decimals: 18, + isNative: true, + roundTo: 5, + logo: "eth-logo.png", }, ]; export const defaultNetwork = - Number(import.meta.env.VITE_DEFAULT_CHAIN_ID) || sepoliaAssets[0].chainId; + Number(import.meta.env.VITE_DEFAULT_CHAIN_ID) || arbSepoliaAssets[0].chainId; -const assets: SupportedAsset[] = - defaultNetwork === 1 ? mainnetAssets : sepoliaAssets; +export const DEFAULT_ASSETS: SupportedAsset[] = + defaultNetwork === 1 ? mainnetAssets : arbSepoliaAssets; // Create mapping by address for quick access: assetByAddress[address] export const defaultNetworkAssetByAddress: Record = {}; -for (const asset of assets) { - defaultNetworkAssetByAddress[asset.address.toLowerCase()] = asset; +for (const asset of DEFAULT_ASSETS) { + defaultNetworkAssetByAddress[BigInt(asset.address).toString()] = asset; } diff --git a/shared/package.json b/shared/package.json index f381d1c..34a885d 100644 --- a/shared/package.json +++ b/shared/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@aztec/bb.js": "3.0.0-nightly.20251104", - "@noir-lang/noir_js": "1.0.0-beta.15", + "@noir-lang/noir_js": "1.0.0-beta.16", "@zkpassport/poseidon2": "^0.6.2", "contracts": "workspace:*", "eciesjs": "^0.4.16",