From 024fc4394c4d5c2233639af9fa587735fe379a01 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Tue, 24 Feb 2026 14:10:25 +0200 Subject: [PATCH 01/24] fix: foundry tests --- packages/mock-contracts/contracts/foundry/CoFheTest.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/mock-contracts/contracts/foundry/CoFheTest.sol b/packages/mock-contracts/contracts/foundry/CoFheTest.sol index 96ded17e..bc276764 100644 --- a/packages/mock-contracts/contracts/foundry/CoFheTest.sol +++ b/packages/mock-contracts/contracts/foundry/CoFheTest.sol @@ -19,9 +19,11 @@ abstract contract CoFheTest is Test { MockACL public mockAcl; MockQueryDecrypter public mockQueryDecrypter; - address constant QUERY_DECRYPTER_ADDRESS = address(512); - address constant ZK_VERIFIER_ADDRESS = address(256); - address constant ZK_VERIFIER_SIGNER_ADDRESS = address(257); + // Keep these in sync with `packages/sdk/core/consts.ts` + address constant ZK_VERIFIER_ADDRESS = 0x0000000000000000000000000000000000005001; + address constant QUERY_DECRYPTER_ADDRESS = 0x0000000000000000000000000000000000005002; + // SDK exposes this as `MOCKS_ZK_VERIFIER_SIGNER_ADDRESS` + address constant ZK_VERIFIER_SIGNER_ADDRESS = SIGNER_ADDRESS; address public constant ACL_ADDRESS = 0xa6Ea4b5291d044D93b73b3CFf3109A1128663E8B; bool private _log = false; From f423eb3a29c89f80069a794d482b16dcce36a27d Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Tue, 24 Feb 2026 14:40:11 +0200 Subject: [PATCH 02/24] tests: decrypt-with-proof draft --- .../contracts/MockTaskManager.sol | 42 ++++++++++++++- .../test/DecryptWithProof.t.sol | 54 +++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 packages/mock-contracts/test/DecryptWithProof.t.sol diff --git a/packages/mock-contracts/contracts/MockTaskManager.sol b/packages/mock-contracts/contracts/MockTaskManager.sol index fd39bdf8..fde91572 100644 --- a/packages/mock-contracts/contracts/MockTaskManager.sol +++ b/packages/mock-contracts/contracts/MockTaskManager.sol @@ -150,6 +150,7 @@ library TMCommon { function getSecAndTypeFromHash(uint256 hash) internal pure returns (uint256) { return uint256((SHIFTED_TYPE_MASK | SECURITY_ZONE_MASK) & hash); } + function isTriviallyEncryptedFromHash(uint256 hash) internal pure returns (bool) { return (hash & TRIVIALLY_ENCRYPTED_MASK) == TRIVIALLY_ENCRYPTED_MASK; } @@ -218,6 +219,9 @@ contract MockTaskManager is ITaskManager, MockCoFHE { address private verifierSigner; + // Signer address for decrypt result verification (threshold network's signing key) + address public decryptResultSigner; + // Storage contract for plaintext results of decrypt operations // PlaintextsStorage public plaintextsStorage; @@ -288,7 +292,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE { // NOTE: MOCK if (block.timestamp < _decryptResultReadyTimestamp[ctHash]) return (0, false); - return (_get(ctHash), true); + return (_decryptResult[ctHash], true); } function checkAllowed(uint256 ctHash) internal view { @@ -460,6 +464,36 @@ contract MockTaskManager is ITaskManager, MockCoFHE { emit ProtocolNotification(ctHash, operation, errorMessage); } + /// @notice Publish a signed decrypt result to the chain + /// @dev Anyone with a valid signature from the decrypt network can call this + function publishDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) external { + _verifyDecryptResult(ctHash, result, signature); + _decryptResultReady[ctHash] = true; + _decryptResult[ctHash] = result; + _decryptResultReadyTimestamp[ctHash] = uint64(block.timestamp); + emit DecryptionResult(ctHash, result, msg.sender); + } + + function _verifyDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) private view { + if (decryptResultSigner == address(0)) revert InvalidAddress(); + bytes32 messageHash = _computeDecryptResultHash(ctHash, result); + (address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecover(messageHash, signature); + + if (err != ECDSA.RecoverError.NoError || recovered == address(0)) { + revert InvalidSignature(); + } + + if (recovered != decryptResultSigner) { + revert InvalidSigner(recovered, decryptResultSigner); + } + } + + /// @notice Format: result (32) || enc_type (4) || chain_id (8) || ct_hash (32) = 76 bytes + function _computeDecryptResultHash(uint256 ctHash, uint256 result) private view returns (bytes32) { + uint8 encryptionType = TMCommon.getUintTypeFromHash(ctHash); + return keccak256(abi.encodePacked(result, uint32(encryptionType), uint64(block.chainid), bytes32(ctHash))); + } + function verifyType(uint8 ctType, uint8 desiredType) internal pure { if (ctType != desiredType) { revert InvalidInputType(ctType, desiredType); @@ -550,6 +584,12 @@ contract MockTaskManager is ITaskManager, MockCoFHE { verifierSigner = signer; } + /// @notice Set the authorized signer for decrypt results + /// @param signer The new signer address (must be non-zero for publishDecryptResult to work) + function setDecryptResultSigner(address signer) external onlyOwner { + decryptResultSigner = signer; + } + function setSecurityZoneMax(int32 securityZone) external onlyOwner { if (securityZone < securityZoneMin) { revert InvalidSecurityZone(securityZone, securityZoneMin, securityZoneMax); diff --git a/packages/mock-contracts/test/DecryptWithProof.t.sol b/packages/mock-contracts/test/DecryptWithProof.t.sol new file mode 100644 index 00000000..6f0b2cc4 --- /dev/null +++ b/packages/mock-contracts/test/DecryptWithProof.t.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import { Test } from 'forge-std/Test.sol'; +import { MockTaskManager } from '../contracts/MockTaskManager.sol'; +import { Utils } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol'; + +contract DecryptWithProofTest is Test { + MockTaskManager private taskManager; + + uint256 private signerPrivateKey; + address private signerAddress; + + function setUp() public { + taskManager = new MockTaskManager(); + taskManager.initialize(address(this)); + + signerPrivateKey = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef; + signerAddress = vm.addr(signerPrivateKey); + + taskManager.setDecryptResultSigner(signerAddress); + } + + function testPublishDecryptResult_happyPath() public { + uint8 securityZone = 0; + uint8 utype = Utils.EUINT32_TFHE; + + uint256 ctHash = _makeHandle(utype, securityZone); + uint256 plaintextResult = 424242; + + bytes memory signature = _signDecryptResult(ctHash, plaintextResult, utype); + + taskManager.publishDecryptResult(ctHash, plaintextResult, signature); + + uint256 onchainResult = taskManager.getDecryptResult(ctHash); + assertEq(onchainResult, plaintextResult); + } + + // ----- helpers ----- + + // TODO: use the same handle generation logic as other test. This is a temp one. + function _makeHandle(uint8 utype, uint8 securityZone) private pure returns (uint256) { + // ctHash format uses the lowest 16 bits for metadata. + // We just need the type bits (byte 1) and securityZone (byte 0). + uint256 base = uint256(keccak256('mock-ct-hash')) & ~uint256(0xFFFF); + return base | (uint256(utype) << 8) | uint256(securityZone); + } + + function _signDecryptResult(uint256 ctHash, uint256 result, uint8 utype) private view returns (bytes memory) { + bytes32 digest = keccak256(abi.encodePacked(result, uint32(utype), uint64(block.chainid), bytes32(ctHash))); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digest); + return abi.encodePacked(r, s, v); + } +} From ee3c7da2d560c826c74023185b332d66ab79207c Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Tue, 24 Feb 2026 17:12:57 +0200 Subject: [PATCH 03/24] test: replace foundry test with hre plugin test --- .../test/decrypt-with-proof.test.ts | 48 +++++++++++++++++ .../test/DecryptWithProof.t.sol | 54 ------------------- 2 files changed, 48 insertions(+), 54 deletions(-) create mode 100644 packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts delete mode 100644 packages/mock-contracts/test/DecryptWithProof.t.sol diff --git a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts new file mode 100644 index 00000000..26321c31 --- /dev/null +++ b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts @@ -0,0 +1,48 @@ +import hre from 'hardhat'; +import { expect } from 'chai'; +import { TASK_COFHE_MOCKS_DEPLOY } from './consts'; +import { Wallet, keccak256, solidityPacked } from 'ethers'; + +// Minimal happy-path test for MockTaskManager.publishDecryptResult +// This verifies we can publish a decrypt result with a valid signature and read it back. + +describe('Decrypt With Proof Test', () => { + it('Should publish decrypt result (happy path)', async () => { + await hre.run(TASK_COFHE_MOCKS_DEPLOY); + + const taskManager = await hre.cofhe.mocks.getMockTaskManager(); + + // Signer used by publishDecryptResult signature verification + const signerPrivateKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; + const signerWallet = new Wallet(signerPrivateKey); + + await taskManager.setDecryptResultSigner(signerWallet.address); + + // ctHash layout: last 2 bytes are metadata + // - byte 0: securityZone + // - byte 1: utype + // For uint32 TFHE, utype is 4 (Utils.EUINT32_TFHE) + const securityZone = 0; + const utype = 4; + + const base = BigInt(keccak256(solidityPacked(['string'], ['mock-ct-hash']))) & ~0xffffn; + const ctHash = base | (BigInt(utype) << 8n) | BigInt(securityZone); + + const result = 424242n; + + const digest = keccak256( + solidityPacked( + ['uint256', 'uint32', 'uint64', 'bytes32'], + [result, utype, BigInt((await hre.ethers.provider.getNetwork()).chainId), hre.ethers.toBeHex(ctHash, 32)] + ) + ); + + const sig = signerWallet.signingKey.sign(digest); + const signature = hre.ethers.concat([sig.r, sig.s, hre.ethers.toBeHex(sig.v, 1)]); + + await taskManager.publishDecryptResult(ctHash, result, signature); + + const onchain = await taskManager.getDecryptResult(ctHash); + expect(onchain).to.equal(result); + }); +}); diff --git a/packages/mock-contracts/test/DecryptWithProof.t.sol b/packages/mock-contracts/test/DecryptWithProof.t.sol deleted file mode 100644 index 6f0b2cc4..00000000 --- a/packages/mock-contracts/test/DecryptWithProof.t.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import { Test } from 'forge-std/Test.sol'; -import { MockTaskManager } from '../contracts/MockTaskManager.sol'; -import { Utils } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol'; - -contract DecryptWithProofTest is Test { - MockTaskManager private taskManager; - - uint256 private signerPrivateKey; - address private signerAddress; - - function setUp() public { - taskManager = new MockTaskManager(); - taskManager.initialize(address(this)); - - signerPrivateKey = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef; - signerAddress = vm.addr(signerPrivateKey); - - taskManager.setDecryptResultSigner(signerAddress); - } - - function testPublishDecryptResult_happyPath() public { - uint8 securityZone = 0; - uint8 utype = Utils.EUINT32_TFHE; - - uint256 ctHash = _makeHandle(utype, securityZone); - uint256 plaintextResult = 424242; - - bytes memory signature = _signDecryptResult(ctHash, plaintextResult, utype); - - taskManager.publishDecryptResult(ctHash, plaintextResult, signature); - - uint256 onchainResult = taskManager.getDecryptResult(ctHash); - assertEq(onchainResult, plaintextResult); - } - - // ----- helpers ----- - - // TODO: use the same handle generation logic as other test. This is a temp one. - function _makeHandle(uint8 utype, uint8 securityZone) private pure returns (uint256) { - // ctHash format uses the lowest 16 bits for metadata. - // We just need the type bits (byte 1) and securityZone (byte 0). - uint256 base = uint256(keccak256('mock-ct-hash')) & ~uint256(0xFFFF); - return base | (uint256(utype) << 8) | uint256(securityZone); - } - - function _signDecryptResult(uint256 ctHash, uint256 result, uint8 utype) private view returns (bytes memory) { - bytes32 digest = keccak256(abi.encodePacked(result, uint32(utype), uint64(block.chainid), bytes32(ctHash))); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digest); - return abi.encodePacked(r, s, v); - } -} From ba5be69ab8eb318d69abbcb4feba9bcf2c2d3471 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 09:23:39 +0200 Subject: [PATCH 04/24] chore: couple annotations --- packages/mock-contracts/contracts/MockTaskManager.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mock-contracts/contracts/MockTaskManager.sol b/packages/mock-contracts/contracts/MockTaskManager.sol index fde91572..dc008971 100644 --- a/packages/mock-contracts/contracts/MockTaskManager.sol +++ b/packages/mock-contracts/contracts/MockTaskManager.sol @@ -292,6 +292,8 @@ contract MockTaskManager is ITaskManager, MockCoFHE { // NOTE: MOCK if (block.timestamp < _decryptResultReadyTimestamp[ctHash]) return (0, false); + // TODO: should it go through mock storage? + // return (_get(ctHash), true); return (_decryptResult[ctHash], true); } @@ -470,6 +472,8 @@ contract MockTaskManager is ITaskManager, MockCoFHE { _verifyDecryptResult(ctHash, result, signature); _decryptResultReady[ctHash] = true; _decryptResult[ctHash] = result; + // TODO: should it go through mock storage? + // _set(ctHash, result); _decryptResultReadyTimestamp[ctHash] = uint64(block.timestamp); emit DecryptionResult(ctHash, result, msg.sender); } From 2a7add1998f7bcce0ce247fafa68c7d3d5e0c19a Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 10:47:40 +0200 Subject: [PATCH 05/24] fix: skip base integration test if it's the default PK --- packages/hardhat-plugin-test/contracts/SimpleTest.sol | 4 ++-- .../test/integration-base-sepolia.test.ts | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/hardhat-plugin-test/contracts/SimpleTest.sol b/packages/hardhat-plugin-test/contracts/SimpleTest.sol index 2c267897..fbd587bf 100644 --- a/packages/hardhat-plugin-test/contracts/SimpleTest.sol +++ b/packages/hardhat-plugin-test/contracts/SimpleTest.sol @@ -13,7 +13,7 @@ contract SimpleTest { function setValueTrivial(uint256 inValue) public { storedValue = FHE.asEuint32(inValue); - storedValueHash = euint32.unwrap(storedValue); + storedValueHash = uint256(euint32.unwrap(storedValue)); FHE.allowThis(storedValue); FHE.allowSender(storedValue); } @@ -24,7 +24,7 @@ contract SimpleTest { */ function setValue(InEuint32 memory inValue) public { storedValue = FHE.asEuint32(inValue); - storedValueHash = euint32.unwrap(storedValue); + storedValueHash = uint256(euint32.unwrap(storedValue)); FHE.allowThis(storedValue); FHE.allowSender(storedValue); } diff --git a/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts b/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts index 85a7d549..60abd891 100644 --- a/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts +++ b/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts @@ -11,8 +11,10 @@ import { PermitUtils } from '@cofhe/sdk/permits'; // Test private key - should be funded on Base Sepolia // Using a well-known test key, but you'll need to fund it with testnet ETH +const DEFAULT_TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; const TEST_PRIVATE_KEY = - process.env.TEST_PRIVATE_KEY || '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; + process.env.TEST_PRIVATE_KEY || + DEFAULT_TEST_PRIVATE_KEY; /* This key is publicly known and should only be used for testing with testnet ETH. Do not use this key on mainnet or with real funds. */ const deployments = { [baseSepolia.id]: { @@ -29,7 +31,7 @@ describe('Base Sepolia Integration Tests', () => { before(async function () { // Skip if no private key is provided (for CI/CD) - if (!process.env.BASE_SEPOLIA_PRIVATE_KEY && process.env.CI) { + if (TEST_PRIVATE_KEY === DEFAULT_TEST_PRIVATE_KEY) { this.skip(); } @@ -90,7 +92,7 @@ describe('Base Sepolia Integration Tests', () => { it('Should encrypt -> store -> decrypt a value', async function () { // Skip if no private key is provided - if (!process.env.BASE_SEPOLIA_PRIVATE_KEY && process.env.CI) { + if (TEST_PRIVATE_KEY === DEFAULT_TEST_PRIVATE_KEY) { this.skip(); } From b960114ecfec5c565c6bab1262c04dd483d0a2d8 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 13:03:12 +0200 Subject: [PATCH 06/24] tmp: switch to local @fhenixprotocol/cofhe-contracts to reach a subfolder which git:/ doesn't support --- packages/hardhat-plugin-test/package.json | 2 +- packages/mock-contracts/package.json | 2 +- pnpm-lock.yaml | 33 +++++------------------ 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/packages/hardhat-plugin-test/package.json b/packages/hardhat-plugin-test/package.json index be19b1c6..37d86f08 100644 --- a/packages/hardhat-plugin-test/package.json +++ b/packages/hardhat-plugin-test/package.json @@ -15,7 +15,7 @@ "@cofhe/sdk": "workspace:*", "@cofhe/hardhat-plugin": "workspace:*", "@cofhe/mock-contracts": "workspace:*", - "@fhenixprotocol/cofhe-contracts": "0.0.13", + "@fhenixprotocol/cofhe-contracts": "link:../../../cofhe-contracts/contracts", "@openzeppelin/contracts": "^5.0.0", "viem": "^2.38.6", "dotenv": "^16.0.0" diff --git a/packages/mock-contracts/package.json b/packages/mock-contracts/package.json index dccea630..65a01136 100644 --- a/packages/mock-contracts/package.json +++ b/packages/mock-contracts/package.json @@ -44,7 +44,7 @@ "dev": "anvil --code-size-limit 100000" }, "dependencies": { - "@fhenixprotocol/cofhe-contracts": "0.0.13", + "@fhenixprotocol/cofhe-contracts": "link:../../../cofhe-contracts/contracts", "@openzeppelin/contracts": "^5.0.0", "@openzeppelin/contracts-upgradeable": "^5.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e332083a..ce93556c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -258,8 +258,8 @@ importers: specifier: workspace:* version: link:../sdk '@fhenixprotocol/cofhe-contracts': - specifier: 0.0.13 - version: 0.0.13 + specifier: link:../../../cofhe-contracts/contracts + version: link:../../../cofhe-contracts/contracts '@nomicfoundation/hardhat-ethers': specifier: ^3.0.5 version: 3.1.0(ethers@6.15.0)(hardhat@2.26.3) @@ -285,8 +285,8 @@ importers: packages/mock-contracts: dependencies: '@fhenixprotocol/cofhe-contracts': - specifier: 0.0.13 - version: 0.0.13 + specifier: link:../../../cofhe-contracts/contracts + version: link:../../../cofhe-contracts/contracts '@openzeppelin/contracts': specifier: ^5.0.0 version: 5.4.0 @@ -2835,6 +2835,7 @@ packages: resolution: {integrity: sha512-+lHo5v52fR7QfQj2ottDw4F/AqZg6obPBRqvK576SJatX3o4aH6ZSt2kxNb5kT8Ckthjw6FoNmLdUVCDpP400w==} dependencies: '@openzeppelin/contracts': 5.4.0 + dev: false /@floating-ui/core@1.7.3: resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} @@ -2987,18 +2988,6 @@ packages: mlly: 1.8.0 dev: false - /@isaacs/balanced-match@4.0.1: - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - dev: true - - /@isaacs/brace-expansion@5.0.0: - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - dependencies: - '@isaacs/balanced-match': 4.0.1 - dev: true - /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -8199,7 +8188,7 @@ packages: resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. dependencies: - minimatch: 10.0.3 + minimatch: 10.2.2 dev: true /@types/minimist@1.2.5: @@ -10366,7 +10355,6 @@ packages: /balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - dev: false /base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -10491,7 +10479,6 @@ packages: engines: {node: 18 || 20 || >=22} dependencies: balanced-match: 4.0.4 - dev: false /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -16466,19 +16453,11 @@ packages: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} dev: true - /minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} - dependencies: - '@isaacs/brace-expansion': 5.0.0 - dev: true - /minimatch@10.2.2: resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==} engines: {node: 18 || 20 || >=22} dependencies: brace-expansion: 5.0.3 - dev: false /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} From bfd4c1b8558bc2a718ae632f1fd1b9aa35bb1671 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 13:05:56 +0200 Subject: [PATCH 07/24] fix: cast uwrap results to uint256 and drop euint256 support --- packages/mock-contracts/contracts/TestBed.sol | 4 +- .../contracts/foundry/CoFheTest.sol | 55 +++++++++---------- packages/mock-contracts/test/TestBed.t.sol | 18 +++--- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/packages/mock-contracts/contracts/TestBed.sol b/packages/mock-contracts/contracts/TestBed.sol index 0175e25f..92365d3e 100644 --- a/packages/mock-contracts/contracts/TestBed.sol +++ b/packages/mock-contracts/contracts/TestBed.sol @@ -13,14 +13,14 @@ contract TestBed { function setNumber(InEuint32 memory inNumber) public { eNumber = FHE.asEuint32(inNumber); - numberHash = euint32.unwrap(eNumber); + numberHash = uint256(euint32.unwrap(eNumber)); FHE.allowThis(eNumber); FHE.allowSender(eNumber); } function setNumberTrivial(uint256 inNumber) public { eNumber = FHE.asEuint32(inNumber); - numberHash = euint32.unwrap(eNumber); + numberHash = uint256(euint32.unwrap(eNumber)); FHE.allowThis(eNumber); FHE.allowSender(eNumber); } diff --git a/packages/mock-contracts/contracts/foundry/CoFheTest.sol b/packages/mock-contracts/contracts/foundry/CoFheTest.sol index bc276764..0045a202 100644 --- a/packages/mock-contracts/contracts/foundry/CoFheTest.sol +++ b/packages/mock-contracts/contracts/foundry/CoFheTest.sol @@ -122,6 +122,7 @@ abstract contract CoFheTest is Test { assertEq(mockTaskManager.inMockStorage(ctHash), true); assertEq(mockTaskManager.mockStorage(ctHash), value); } + function assertHashValue(uint256 ctHash, uint256 value, string memory message) public view { assertEq(mockTaskManager.inMockStorage(ctHash), true, message); assertEq(mockTaskManager.mockStorage(ctHash), value, message); @@ -130,49 +131,61 @@ abstract contract CoFheTest is Test { // Encrypted types (no message) function assertHashValue(ebool eValue, bool value) public view { - assertHashValue(ebool.unwrap(eValue), value ? 1 : 0); + assertHashValue(uint256(ebool.unwrap(eValue)), value ? 1 : 0); } + function assertHashValue(euint8 eValue, uint8 value) public view { - assertHashValue(euint8.unwrap(eValue), value); + assertHashValue(uint256(euint8.unwrap(eValue)), value); } + function assertHashValue(euint16 eValue, uint16 value) public view { - assertHashValue(euint16.unwrap(eValue), value); + assertHashValue(uint256(euint16.unwrap(eValue)), value); } + function assertHashValue(euint32 eValue, uint32 value) public view { - assertHashValue(euint32.unwrap(eValue), value); + assertHashValue(uint256(euint32.unwrap(eValue)), value); } + function assertHashValue(euint64 eValue, uint64 value) public view { - assertHashValue(euint64.unwrap(eValue), value); + assertHashValue(uint256(euint64.unwrap(eValue)), value); } + function assertHashValue(euint128 eValue, uint128 value) public view { - assertHashValue(euint128.unwrap(eValue), value); + assertHashValue(uint256(euint128.unwrap(eValue)), value); } + function assertHashValue(eaddress eValue, address value) public view { - assertHashValue(eaddress.unwrap(eValue), uint256(uint160(value))); + assertHashValue(uint256(eaddress.unwrap(eValue)), uint256(uint160(value))); } // Encrypted types (with message) function assertHashValue(ebool eValue, bool value, string memory message) public view { - assertHashValue(ebool.unwrap(eValue), value ? 1 : 0, message); + assertHashValue(uint256(ebool.unwrap(eValue)), value ? 1 : 0, message); } + function assertHashValue(euint8 eValue, uint8 value, string memory message) public view { - assertHashValue(euint8.unwrap(eValue), value, message); + assertHashValue(uint256(euint8.unwrap(eValue)), value, message); } + function assertHashValue(euint16 eValue, uint16 value, string memory message) public view { - assertHashValue(euint16.unwrap(eValue), value, message); + assertHashValue(uint256(euint16.unwrap(eValue)), value, message); } + function assertHashValue(euint32 eValue, uint32 value, string memory message) public view { - assertHashValue(euint32.unwrap(eValue), value, message); + assertHashValue(uint256(euint32.unwrap(eValue)), value, message); } + function assertHashValue(euint64 eValue, uint64 value, string memory message) public view { - assertHashValue(euint64.unwrap(eValue), value, message); + assertHashValue(uint256(euint64.unwrap(eValue)), value, message); } + function assertHashValue(euint128 eValue, uint128 value, string memory message) public view { - assertHashValue(euint128.unwrap(eValue), value, message); + assertHashValue(uint256(euint128.unwrap(eValue)), value, message); } + function assertHashValue(eaddress eValue, address value, string memory message) public view { - assertHashValue(eaddress.unwrap(eValue), uint256(uint160(value)), message); + assertHashValue(uint256(eaddress.unwrap(eValue)), uint256(uint160(value)), message); } // UTILS @@ -260,16 +273,6 @@ abstract contract CoFheTest is Test { return abi.decode(abi.encode(createEncryptedInput(Utils.EUINT128_TFHE, value, securityZone, sender)), (InEuint128)); } - /** - * @notice Creates an InEuint256 to be used as FHE input. Value is stored in MockCoFHE contract, hash is a pointer to that value. - * @param value Value to encrypt. - * @param securityZone Security zone of the encrypted value. - * @return InEuint256. - */ - function createInEuint256(uint256 value, uint8 securityZone, address sender) public returns (InEuint256 memory) { - return abi.decode(abi.encode(createEncryptedInput(Utils.EUINT256_TFHE, value, securityZone, sender)), (InEuint256)); - } - /** * @notice Creates an InEaddress to be used as FHE input. Value is stored in MockCoFHE contract, hash is a pointer to that value. * @param value Value to encrypt. @@ -310,10 +313,6 @@ abstract contract CoFheTest is Test { return createInEuint128(value, 0, sender); } - function createInEuint256(uint256 value, address sender) public returns (InEuint256 memory) { - return createInEuint256(value, 0, sender); - } - function createInEaddress(address value, address sender) public returns (InEaddress memory) { return createInEaddress(value, 0, sender); } diff --git a/packages/mock-contracts/test/TestBed.t.sol b/packages/mock-contracts/test/TestBed.t.sol index ed92f336..b4a849a6 100644 --- a/packages/mock-contracts/test/TestBed.t.sol +++ b/packages/mock-contracts/test/TestBed.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.13; import { Test } from 'forge-std/Test.sol'; import { TestBed } from '../contracts/TestBed.sol'; import { CoFheTest } from '../contracts/foundry/CoFheTest.sol'; -import { FHE, InEuint32, euint8, euint256 } from '@fhenixprotocol/cofhe-contracts/FHE.sol'; +import { FHE, InEuint32, euint8, euint128 } from '@fhenixprotocol/cofhe-contracts/FHE.sol'; contract TestBedTest is Test, CoFheTest { TestBed private testbed; @@ -34,7 +34,7 @@ contract TestBedTest is Test, CoFheTest { euint8 b = FHE.asEuint8(240); euint8 c = FHE.add(a, b); - assertHashValue(euint8.unwrap(c), (240 + 240) % 256); + assertHashValue(uint256(euint8.unwrap(c)), (240 + 240) % 256); } function testDivideByZero() public { @@ -42,19 +42,19 @@ contract TestBedTest is Test, CoFheTest { euint8 b = FHE.asEuint8(0); euint8 c = FHE.div(a, b); - assertHashValue(euint8.unwrap(c), type(uint8).max); + assertHashValue(uint256(euint8.unwrap(c)), type(uint8).max); } - function test256BitsNoOverflow() public { - euint256 a = FHE.asEuint256(type(uint256).max); - euint256 b = FHE.asEuint256(type(uint256).max); - euint256 c = FHE.add(a, b); + function test128BitsNoOverflow() public { + euint128 a = FHE.asEuint128(type(uint128).max); + euint128 b = FHE.asEuint128(type(uint128).max); + euint128 c = FHE.add(a, b); uint256 expected; unchecked { - expected = type(uint256).max + type(uint256).max; + expected = type(uint128).max + type(uint128).max; } - assertHashValue(euint256.unwrap(c), expected); + assertHashValue(uint256(euint128.unwrap(c)), expected); } } From aea164cd02c557cc185b0cf77eee523699985972 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 13:06:45 +0200 Subject: [PATCH 08/24] fix: add new fn implementations for MockTaskManager --- .../contracts/MockTaskManager.sol | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/mock-contracts/contracts/MockTaskManager.sol b/packages/mock-contracts/contracts/MockTaskManager.sol index dc008971..fa6b82e6 100644 --- a/packages/mock-contracts/contracts/MockTaskManager.sol +++ b/packages/mock-contracts/contracts/MockTaskManager.sol @@ -478,6 +478,19 @@ contract MockTaskManager is ITaskManager, MockCoFHE { emit DecryptionResult(ctHash, result, msg.sender); } + function publishDecryptResultBatch( + uint256[] calldata ctHashes, + uint256[] calldata results, + bytes[] calldata signatures + ) external { + // Mock implementation: process each result individually + // Note: publishDecryptResult is defined later in the contract + for (uint256 i = 0; i < ctHashes.length; i++) { + // Call via external interface to avoid forward reference issue + this.publishDecryptResult(ctHashes[i], results[i], signatures[i]); + } + } + function _verifyDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) private view { if (decryptResultSigner == address(0)) revert InvalidAddress(); bytes32 messageHash = _computeDecryptResultHash(ctHash, result); @@ -634,4 +647,35 @@ contract MockTaskManager is ITaskManager, MockCoFHE { function isAllowedWithPermission(Permission memory permission, uint256 handle) public view returns (bool) { return acl.isAllowedWithPermission(permission, handle); } + + // Stub implementations for new ITaskManager interface methods (inc PR #48) + + function createRandomTask(uint8 returnType, uint256 seed, int32 securityZone) external returns (uint256) { + // Mock implementation: just return a pseudo-random hash based on seed + return uint256(keccak256(abi.encode(returnType, seed, securityZone, block.timestamp))); + } + + function isPubliclyAllowed(uint256 ctHash) external view returns (bool) { + // Mock implementation: allow all for now + return true; + } + + function verifyDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) external view returns (bool) { + // Mock implementation: verify signature using the verifier signer + bytes32 digest = keccak256(abi.encodePacked(result)); + return ECDSA.recover(digest, signature) == verifierSigner; + } + + function verifyDecryptResultSafe( + uint256 ctHash, + uint256 result, + bytes calldata signature + ) external view returns (bool) { + // Same as verifyDecryptResult for mock + try this.verifyDecryptResult(ctHash, result, signature) returns (bool valid) { + return valid; + } catch { + return false; + } + } } From c35495c41c687470431102a90cc2cf9c2ad9a395 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 13:12:10 +0200 Subject: [PATCH 09/24] chore: update artefacts --- packages/mock-contracts/src/MockACL.ts | 2 +- .../mock-contracts/src/MockQueryDecrypter.ts | 2 +- .../mock-contracts/src/MockTaskManager.ts | 180 +++++++++++++++++- packages/mock-contracts/src/MockZkVerifier.ts | 2 +- packages/mock-contracts/src/TestBed.ts | 8 +- 5 files changed, 186 insertions(+), 8 deletions(-) diff --git a/packages/mock-contracts/src/MockACL.ts b/packages/mock-contracts/src/MockACL.ts index 5b771eca..b5bc88bc 100644 --- a/packages/mock-contracts/src/MockACL.ts +++ b/packages/mock-contracts/src/MockACL.ts @@ -616,5 +616,5 @@ export const MockACLArtifact = { }, ], bytecode: - '0x610160604052348015610010575f5ffd5b506040518060400160405280600381526020017f41434c00000000000000000000000000000000000000000000000000000000008152506040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506100905f8361012b60201b90919060201c565b61012081815250506100ac60018261012b60201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506100e961017860201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1681525050505061072d565b5f60208351101561014c57610145836101d260201b60201c565b9050610172565b8261015c8361023760201b60201c565b5f01908161016a919061048e565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016101b79594939291906105c3565b60405160208183030381529060405280519060200120905090565b5f5f829050601f8151111561021e57826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401610215919061067a565b60405180910390fd5b80518161022a906106c7565b5f1c175f1b915050919050565b5f819050919050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806102bb57607f821691505b6020821081036102ce576102cd610277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102f5565b61033a86836102f5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61037e61037961037484610352565b61035b565b610352565b9050919050565b5f819050919050565b61039783610364565b6103ab6103a382610385565b848454610301565b825550505050565b5f5f905090565b6103c26103b3565b6103cd81848461038e565b505050565b5f5b828110156103f3576103e85f8284016103ba565b6001810190506103d4565b505050565b601f821115610446578282111561044557610412816102d4565b61041b836102e6565b610424856102e6565b6020861015610431575f90505b808301610440828403826103d2565b505050505b5b505050565b5f82821c905092915050565b5f6104665f198460080261044b565b1980831691505092915050565b5f61047e8383610457565b9150826002028217905092915050565b61049782610240565b67ffffffffffffffff8111156104b0576104af61024a565b5b6104ba82546102a4565b6104c58282856103f8565b5f60209050601f8311600181146104f6575f84156104e4578287015190505b6104ee8582610473565b865550610555565b601f198416610504866102d4565b5f5b8281101561052b57848901518255600182019150602085019450602081019050610506565b868310156105485784890151610544601f891682610457565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b61056f8161055d565b82525050565b61057e81610352565b82525050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6105ad82610584565b9050919050565b6105bd816105a3565b82525050565b5f60a0820190506105d65f830188610566565b6105e36020830187610566565b6105f06040830186610566565b6105fd6060830185610575565b61060a60808301846105b4565b9695505050505050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61064c82610240565b6106568185610614565b9350610666818560208601610624565b61066f81610632565b840191505092915050565b5f6020820190508181035f8301526106928184610642565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f6106be825161055d565b80915050919050565b5f6106d18261069a565b826106db846106a4565b90506106e6816106b3565b92506020821015610726576107217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026102f5565b831692505b5050919050565b60805160a05160c05160e05161010051610120516101405161309261077e5f395f6117a301525f61176801525f611ec701525f611ea601525f611a9001525f611ae601525f611b0f01526130925ff3fe608060405234801561000f575f5ffd5b506004361061012a575f3560e01c806365ce8df7116100ab57806394d9184c1161006f57806394d9184c14610334578063a8b7010014610364578063ae79f04a14610380578063cbf4f703146103b0578063ccd9a7cd146103e05761012a565b806365ce8df71461028a57806379a3a7fb146102a85780637a9a598e146102c4578063846cd433146102f457806384b0196e146103105761012a565b8063484de822116100f2578063484de822146101c05780634980f288146101dc57806351b8fd201461020c5780635faa299a1461022a5780636330a7091461025a5761012a565b80630d8e6e2c1461012e578063267c4ae41461014c57806335334c231461016a57806337e6b44f146101745780633c3839ba146101a4575b5f5ffd5b610136610410565b604051610143919061212e565b60405180910390f35b61015461048b565b6040516101619190612168565b60405180910390f35b610172610493565b005b61018e6004803603810190610189919061221f565b610544565b60405161019b9190612168565b60405180910390f35b6101be60048036038101906101b9919061239d565b6105b4565b005b6101da60048036038101906101d591906123f7565b610735565b005b6101f660048036038101906101f1919061247a565b610896565b60405161020391906124b4565b60405180910390f35b6102146108a7565b60405161022191906124dc565b60405180910390f35b610244600480360381019061023f919061221f565b6108bf565b6040516102519190612168565b60405180910390f35b610274600480360381019061026f91906124f5565b6108f3565b6040516102819190612168565b60405180910390f35b610292610927565b60405161029f91906124dc565b60405180910390f35b6102c260048036038101906102bd91906123f7565b610942565b005b6102de60048036038101906102d9919061221f565b610a88565b6040516102eb9190612168565b60405180910390f35b61030e6004803603810190610309919061221f565b610ac5565b005b610318610bce565b60405161032b9796959493929190612620565b60405180910390f35b61034e600480360381019061034991906124f5565b610c73565b60405161035b9190612168565b60405180910390f35b61037e600480360381019061037991906126a2565b610ca6565b005b61039a600480360381019061039591906128d4565b610fd6565b6040516103a79190612168565b60405180910390f35b6103ca60048036038101906103c5919061292e565b61122d565b6040516103d79190612168565b60405180910390f35b6103fa60048036038101906103f59190612975565b611478565b6040516104079190612168565b60405180910390f35b60606040518060400160405280600381526020017f41434c00000000000000000000000000000000000000000000000000000000008152506104515f611617565b61045b6001611617565b6104645f611617565b6040516020016104779493929190612aa7565b604051602081830303815290604052905090565b5f6001905090565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461051757336040517f3809a24300000000000000000000000000000000000000000000000000000000815260040161050e91906124dc565b60405180910390fd5b5f5c5f5f5d6001810160015b8181101561053f57805c5f825d5f815d50600181019050610523565b505050565b5f5f61054e6116e1565b9050806001015f8581526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1691505092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461063857336040517f3809a24300000000000000000000000000000000000000000000000000000000815260040161062f91906124dc565b60405180910390fd5b5f825190505f6106466116e1565b90505f5f90505b828110156106f7575f85828151811061066957610668612b05565b5b6020026020010151905061067d81866108bf565b6106be57846040517fd0d259760000000000000000000000000000000000000000000000000000000081526004016106b591906124dc565b60405180910390fd5b6001836002015f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555050808060010191505061064d565b507f2fd616621b8415a2efb27b224024340ac767797553ce6fdf4c1adefd160504c6846040516107279190612b32565b60405180910390a150505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107b957336040517f3809a2430000000000000000000000000000000000000000000000000000000081526004016107b091906124dc565b60405180910390fd5b6107c383826108bf565b158015610810575073ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1561085257806040517fd0d2597600000000000000000000000000000000000000000000000000000000815260040161084991906124dc565b60405180910390fd5b5f8383604051602001610866929190612bb7565b6040516020818303038152906040528051906020012090506001815d5f5c6001810182815d805f5d505050505050565b5f6108a082611747565b9050919050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d981565b5f6108ca8383610a88565b806108db57506108da8383610544565b5b806108eb57506108ea83610c73565b5b905092915050565b5f5f6108fd6116e1565b9050806002015f8481526020019081526020015f205f9054906101000a900460ff16915050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d9905090565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109c657336040517f3809a2430000000000000000000000000000000000000000000000000000000081526004016109bd91906124dc565b60405180910390fd5b6109d083826108bf565b610a1157806040517fd0d25976000000000000000000000000000000000000000000000000000000008152600401610a0891906124dc565b60405180910390fd5b5f610a1a6116e1565b90506001816001015f8681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050505050565b5f5f5f8484604051602001610a9e929190612bb7565b604051602081830303815290604052805190602001209050805c9150819250505092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4957336040517f3809a243000000000000000000000000000000000000000000000000000000008152600401610b4091906124dc565b60405180910390fd5b610b5382826108bf565b610b9457806040517fd0d25976000000000000000000000000000000000000000000000000000000008152600401610b8b91906124dc565b60405180910390fd5b5f610b9d6116e1565b90506001815f015f8581526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b5f6060805f5f5f6060610bdf611760565b610be761179a565b46305f5f1b5f67ffffffffffffffff811115610c0657610c05612261565b5b604051908082528060200260200182016040528015610c345781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f5f610c7d6116e1565b9050805f015f8481526020019081526020015f205f9054906101000a900460ff16915050919050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d2a57336040517f3809a243000000000000000000000000000000000000000000000000000000008152600401610d2191906124dc565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d8f576040517f30dc920300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610d986116e1565b9050806003015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615610e93576040517fd186046800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816003015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff03b7c0d4879b0bcbbf440794871f139c96fd13a145a8172b33b9cab5fa2830a60405160405180910390a4505050565b5f8242816020015167ffffffffffffffff161015611020576040517fed0764a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611042815f0151611038611033846117d5565b611747565b8360c0015161182e565b611078576040517f4c40eccb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16141580156110d857506110d681604001516110cc6110c7846118da565b611747565b8360e0015161182e565b155b1561110f576040517f8e143bf700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81606001511415801561115357505f73ffffffffffffffffffffffffffffffffffffffff16816080015173ffffffffffffffffffffffffffffffffffffffff1614155b80156111e05750806080015173ffffffffffffffffffffffffffffffffffffffff1663b63391e8825f015183606001516040518363ffffffff1660e01b81526004016111a0929190612be2565b602060405180830381865afa1580156111bb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111df9190612c33565b5b15611217576040517fcbd3a96600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61122483855f01516108bf565b91505092915050565b5f8142816020015167ffffffffffffffff161015611277576040517fed0764a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611299815f015161128f61128a846117d5565b611747565b8360c0015161182e565b6112cf576040517f4c40eccb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161415801561132f575061132d816040015161132361131e846118da565b611747565b8360e0015161182e565b155b15611366576040517f8e143bf700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8160600151141580156113aa57505f73ffffffffffffffffffffffffffffffffffffffff16816080015173ffffffffffffffffffffffffffffffffffffffff1614155b80156114375750806080015173ffffffffffffffffffffffffffffffffffffffff1663b63391e8825f015183606001516040518363ffffffff1660e01b81526004016113f7929190612be2565b602060405180830381865afa158015611412573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114369190612c33565b5b1561146e576040517fcbd3a96600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001915050919050565b5f5f6114826116e1565b9050806001015f8681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1680156115425750806001015f8681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b801561160c5750806003015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b915050949350505050565b60605f60016116258461193c565b0190505f8167ffffffffffffffff81111561164357611642612261565b5b6040519080825280601f01601f1916602001820160405280156116755781602001600182028036833780820191505090505b5090505f82602083010190505b6001156116d6578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816116cb576116ca612c5e565b5b0494505f8503611682575b819350505050919050565b5f5f60ff5f1b1960017fc4eb438ffad04c606bb4f9c3576c0f142d5dc3782731029ea1ab95b6483220115f1c6117179190612cb8565b6040516020016117279190612ceb565b604051602081830303815290604052805190602001201690508091505090565b5f611759611753611a8d565b83611b43565b9050919050565b60606117955f7f0000000000000000000000000000000000000000000000000000000000000000611b8390919063ffffffff16565b905090565b60606117d060017f0000000000000000000000000000000000000000000000000000000000000000611b8390919063ffffffff16565b905090565b5f5f73ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff160361181d5761181682611c30565b9050611829565b61182682611ca2565b90505b919050565b5f5f8473ffffffffffffffffffffffffffffffffffffffff163b036118c5575f5f6118598585611d0e565b50915091505f600381111561187157611870612d04565b5b81600381111561188457611883612d04565b5b1480156118bc57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b925050506118d3565b6118d0848484611d63565b90505b9392505050565b5f7f82af07a6c9eb6bb31a0c86f7f5cad0039589750ad5b4b925ed5741f7ad4e8d4b8260a001518360c001518051906020012060405160200161191f93929190612d31565b604051602081830303815290604052805190602001209050919050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611998577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161198e5761198d612c5e565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106119d5576d04ee2d6d415b85acef810000000083816119cb576119ca612c5e565b5b0492506020810190505b662386f26fc100008310611a0457662386f26fc1000083816119fa576119f9612c5e565b5b0492506010810190505b6305f5e1008310611a2d576305f5e1008381611a2357611a22612c5e565b5b0492506008810190505b6127108310611a52576127108381611a4857611a47612c5e565b5b0492506004810190505b60648310611a755760648381611a6b57611a6a612c5e565b5b0492506002810190505b600a8310611a84576001810190505b80915050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611b0857507f000000000000000000000000000000000000000000000000000000000000000046145b15611b35577f00000000000000000000000000000000000000000000000000000000000000009050611b40565b611b3d611e82565b90505b90565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b606060ff5f1b8314611b9f57611b9883611f17565b9050611c2a565b818054611bab90612d93565b80601f0160208091040260200160405190810160405280929190818152602001828054611bd790612d93565b8015611c225780601f10611bf957610100808354040283529160200191611c22565b820191905f5260205f20905b815481529060010190602001808311611c0557829003601f168201915b505050505090505b92915050565b5f7f0ce0d938c38f948b8f9cf16098cd15ec62de132c8d422719ad270c5e2a101102825f015183602001518460400151856060015186608001518760a00151604051602001611c859796959493929190612dd2565b604051602081830303815290604052805190602001209050919050565b5f7f8549e986c64faf9b741179c61561f9d39f337cf9739f86178d84dabc6ca4cad5825f01518360200151846040015185606001518660800151604051602001611cf196959493929190612e3f565b604051602081830303815290604052805190602001209050919050565b5f5f5f6041845103611d4e575f5f5f602087015192506040870151915060608701515f1a9050611d4088828585611f89565b955095509550505050611d5c565b5f600285515f1b9250925092505b9250925092565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff168585604051602401611d90929190612ef0565b604051602081830303815290604052631626ba7e60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611de29190612f58565b5f60405180830381855afa9150503d805f8114611e1a576040519150601f19603f3d011682016040523d82523d5f602084013e611e1f565b606091505b5091509150818015611e3357506020815110155b8015611e775750631626ba7e60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681806020019051810190611e759190612f82565b145b925050509392505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000004630604051602001611efc959493929190612fad565b60405160208183030381529060405280519060200120905090565b60605f611f2383612070565b90505f602067ffffffffffffffff811115611f4157611f40612261565b5b6040519080825280601f01601f191660200182016040528015611f735781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115611fc5575f600385925092509250612066565b5f6001888888886040515f8152602001604052604051611fe89493929190613019565b6020604051602081039080840390855afa158015612008573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612059575f60015f5f1b93509350935050612066565b805f5f5f1b935093509350505b9450945094915050565b5f5f60ff835f1c169050601f8111156120b5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612100826120be565b61210a81856120c8565b935061211a8185602086016120d8565b612123816120e6565b840191505092915050565b5f6020820190508181035f83015261214681846120f6565b905092915050565b5f8115159050919050565b6121628161214e565b82525050565b5f60208201905061217b5f830184612159565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b6121a481612192565b81146121ae575f5ffd5b50565b5f813590506121bf8161219b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6121ee826121c5565b9050919050565b6121fe816121e4565b8114612208575f5ffd5b50565b5f81359050612219816121f5565b92915050565b5f5f604083850312156122355761223461218a565b5b5f612242858286016121b1565b92505060206122538582860161220b565b9150509250929050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612297826120e6565b810181811067ffffffffffffffff821117156122b6576122b5612261565b5b80604052505050565b5f6122c8612181565b90506122d4828261228e565b919050565b5f67ffffffffffffffff8211156122f3576122f2612261565b5b602082029050602081019050919050565b5f5ffd5b5f61231a612315846122d9565b6122bf565b9050808382526020820190506020840283018581111561233d5761233c612304565b5b835b81811015612366578061235288826121b1565b84526020840193505060208101905061233f565b5050509392505050565b5f82601f8301126123845761238361225d565b5b8135612394848260208601612308565b91505092915050565b5f5f604083850312156123b3576123b261218a565b5b5f83013567ffffffffffffffff8111156123d0576123cf61218e565b5b6123dc85828601612370565b92505060206123ed8582860161220b565b9150509250929050565b5f5f5f6060848603121561240e5761240d61218a565b5b5f61241b868287016121b1565b935050602061242c8682870161220b565b925050604061243d8682870161220b565b9150509250925092565b5f819050919050565b61245981612447565b8114612463575f5ffd5b50565b5f8135905061247481612450565b92915050565b5f6020828403121561248f5761248e61218a565b5b5f61249c84828501612466565b91505092915050565b6124ae81612447565b82525050565b5f6020820190506124c75f8301846124a5565b92915050565b6124d6816121e4565b82525050565b5f6020820190506124ef5f8301846124cd565b92915050565b5f6020828403121561250a5761250961218a565b5b5f612517848285016121b1565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61255481612520565b82525050565b61256381612192565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61259b81612192565b82525050565b5f6125ac8383612592565b60208301905092915050565b5f602082019050919050565b5f6125ce82612569565b6125d88185612573565b93506125e383612583565b805f5b838110156126135781516125fa88826125a1565b9750612605836125b8565b9250506001810190506125e6565b5085935050505092915050565b5f60e0820190506126335f83018a61254b565b818103602083015261264581896120f6565b9050818103604083015261265981886120f6565b9050612668606083018761255a565b61267560808301866124cd565b61268260a08301856124a5565b81810360c083015261269481846125c4565b905098975050505050505050565b5f5f604083850312156126b8576126b761218a565b5b5f6126c58582860161220b565b92505060206126d68582860161220b565b9150509250929050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82169050919050565b612704816126e8565b811461270e575f5ffd5b50565b5f8135905061271f816126fb565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561274357612742612261565b5b61274c826120e6565b9050602081019050919050565b828183375f83830152505050565b5f61277961277484612729565b6122bf565b90508281526020810184848401111561279557612794612725565b5b6127a0848285612759565b509392505050565b5f82601f8301126127bc576127bb61225d565b5b81356127cc848260208601612767565b91505092915050565b5f61010082840312156127eb576127ea6126e0565b5b6127f66101006122bf565b90505f6128058482850161220b565b5f83015250602061281884828501612711565b602083015250604061282c8482850161220b565b6040830152506060612840848285016121b1565b60608301525060806128548482850161220b565b60808301525060a061286884828501612466565b60a08301525060c082013567ffffffffffffffff81111561288c5761288b6126e4565b5b612898848285016127a8565b60c08301525060e082013567ffffffffffffffff8111156128bc576128bb6126e4565b5b6128c8848285016127a8565b60e08301525092915050565b5f5f604083850312156128ea576128e961218a565b5b5f83013567ffffffffffffffff8111156129075761290661218e565b5b612913858286016127d5565b9250506020612924858286016121b1565b9150509250929050565b5f602082840312156129435761294261218a565b5b5f82013567ffffffffffffffff8111156129605761295f61218e565b5b61296c848285016127d5565b91505092915050565b5f5f5f5f6080858703121561298d5761298c61218a565b5b5f61299a8782880161220b565b94505060206129ab878288016121b1565b93505060406129bc8782880161220b565b92505060606129cd8782880161220b565b91505092959194509250565b5f81905092915050565b5f6129ed826120be565b6129f781856129d9565b9350612a078185602086016120d8565b80840191505092915050565b7f20760000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a476002836129d9565b9150612a5282612a13565b600282019050919050565b7f2e000000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a916001836129d9565b9150612a9c82612a5d565b600182019050919050565b5f612ab282876129e3565b9150612abd82612a3b565b9150612ac982866129e3565b9150612ad482612a85565b9150612ae082856129e3565b9150612aeb82612a85565b9150612af782846129e3565b915081905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6020820190508181035f830152612b4a81846125c4565b905092915050565b5f819050919050565b612b6c612b6782612192565b612b52565b82525050565b5f8160601b9050919050565b5f612b8882612b72565b9050919050565b5f612b9982612b7e565b9050919050565b612bb1612bac826121e4565b612b8f565b82525050565b5f612bc28285612b5b565b602082019150612bd28284612ba0565b6014820191508190509392505050565b5f604082019050612bf55f8301856124cd565b612c02602083018461255a565b9392505050565b612c128161214e565b8114612c1c575f5ffd5b50565b5f81519050612c2d81612c09565b92915050565b5f60208284031215612c4857612c4761218a565b5b5f612c5584828501612c1f565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612cc282612192565b9150612ccd83612192565b9250828203905081811115612ce557612ce4612c8b565b5b92915050565b5f602082019050612cfe5f83018461255a565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f606082019050612d445f8301866124a5565b612d5160208301856124a5565b612d5e60408301846124a5565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612daa57607f821691505b602082108103612dbd57612dbc612d66565b5b50919050565b612dcc816126e8565b82525050565b5f60e082019050612de55f83018a6124a5565b612df260208301896124cd565b612dff6040830188612dc3565b612e0c60608301876124cd565b612e19608083018661255a565b612e2660a08301856124cd565b612e3360c08301846124a5565b98975050505050505050565b5f60c082019050612e525f8301896124a5565b612e5f60208301886124cd565b612e6c6040830187612dc3565b612e7960608301866124cd565b612e86608083018561255a565b612e9360a08301846124cd565b979650505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f612ec282612e9e565b612ecc8185612ea8565b9350612edc8185602086016120d8565b612ee5816120e6565b840191505092915050565b5f604082019050612f035f8301856124a5565b8181036020830152612f158184612eb8565b90509392505050565b5f81905092915050565b5f612f3282612e9e565b612f3c8185612f1e565b9350612f4c8185602086016120d8565b80840191505092915050565b5f612f638284612f28565b915081905092915050565b5f81519050612f7c81612450565b92915050565b5f60208284031215612f9757612f9661218a565b5b5f612fa484828501612f6e565b91505092915050565b5f60a082019050612fc05f8301886124a5565b612fcd60208301876124a5565b612fda60408301866124a5565b612fe7606083018561255a565b612ff460808301846124cd565b9695505050505050565b5f60ff82169050919050565b61301381612ffe565b82525050565b5f60808201905061302c5f8301876124a5565b613039602083018661300a565b61304660408301856124a5565b61305360608301846124a5565b9594505050505056fea2646970667358221220c1b0725ded5df0811b7b8342782a90ab3299da6ab25244ee43ee4f5053ca1e3d64736f6c63430008210033', + '0x610160604052348015610010575f5ffd5b506040518060400160405280600381526020017f41434c00000000000000000000000000000000000000000000000000000000008152506040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506100905f8361012b60201b90919060201c565b61012081815250506100ac60018261012b60201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506100e961017860201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1681525050505061071c565b5f60208351101561014c57610145836101d260201b60201c565b9050610172565b8261015c8361023760201b60201c565b5f01908161016a919061047d565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016101b79594939291906105b2565b60405160208183030381529060405280519060200120905090565b5f5f829050601f8151111561021e57826040517f305a27a90000000000000000000000000000000000000000000000000000000081526004016102159190610669565b60405180910390fd5b80518161022a906106b6565b5f1c175f1b915050919050565b5f819050919050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806102bb57607f821691505b6020821081036102ce576102cd610277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102f5565b61033a86836102f5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61037e61037961037484610352565b61035b565b610352565b9050919050565b5f819050919050565b61039783610364565b6103ab6103a382610385565b848454610301565b825550505050565b5f5f905090565b6103c26103b3565b6103cd81848461038e565b505050565b5b818110156103f0576103e55f826103ba565b6001810190506103d3565b5050565b601f82111561043557610406816102d4565b61040f846102e6565b8101602085101561041e578190505b61043261042a856102e6565b8301826103d2565b50505b505050565b5f82821c905092915050565b5f6104555f198460080261043a565b1980831691505092915050565b5f61046d8383610446565b9150826002028217905092915050565b61048682610240565b67ffffffffffffffff81111561049f5761049e61024a565b5b6104a982546102a4565b6104b48282856103f4565b5f60209050601f8311600181146104e5575f84156104d3578287015190505b6104dd8582610462565b865550610544565b601f1984166104f3866102d4565b5f5b8281101561051a578489015182556001820191506020850194506020810190506104f5565b868310156105375784890151610533601f891682610446565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b61055e8161054c565b82525050565b61056d81610352565b82525050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61059c82610573565b9050919050565b6105ac81610592565b82525050565b5f60a0820190506105c55f830188610555565b6105d26020830187610555565b6105df6040830186610555565b6105ec6060830185610564565b6105f960808301846105a3565b9695505050505050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61063b82610240565b6106458185610603565b9350610655818560208601610613565b61065e81610621565b840191505092915050565b5f6020820190508181035f8301526106818184610631565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f6106ad825161054c565b80915050919050565b5f6106c082610689565b826106ca84610693565b90506106d5816106a2565b92506020821015610715576107107fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026102f5565b831692505b5050919050565b60805160a05160c05160e05161010051610120516101405161309261076d5f395f6117a301525f61176801525f611ec701525f611ea601525f611a9001525f611ae601525f611b0f01526130925ff3fe608060405234801561000f575f5ffd5b506004361061012a575f3560e01c806365ce8df7116100ab57806394d9184c1161006f57806394d9184c14610334578063a8b7010014610364578063ae79f04a14610380578063cbf4f703146103b0578063ccd9a7cd146103e05761012a565b806365ce8df71461028a57806379a3a7fb146102a85780637a9a598e146102c4578063846cd433146102f457806384b0196e146103105761012a565b8063484de822116100f2578063484de822146101c05780634980f288146101dc57806351b8fd201461020c5780635faa299a1461022a5780636330a7091461025a5761012a565b80630d8e6e2c1461012e578063267c4ae41461014c57806335334c231461016a57806337e6b44f146101745780633c3839ba146101a4575b5f5ffd5b610136610410565b604051610143919061212e565b60405180910390f35b61015461048b565b6040516101619190612168565b60405180910390f35b610172610493565b005b61018e6004803603810190610189919061221f565b610544565b60405161019b9190612168565b60405180910390f35b6101be60048036038101906101b9919061239d565b6105b4565b005b6101da60048036038101906101d591906123f7565b610735565b005b6101f660048036038101906101f1919061247a565b610896565b60405161020391906124b4565b60405180910390f35b6102146108a7565b60405161022191906124dc565b60405180910390f35b610244600480360381019061023f919061221f565b6108bf565b6040516102519190612168565b60405180910390f35b610274600480360381019061026f91906124f5565b6108f3565b6040516102819190612168565b60405180910390f35b610292610927565b60405161029f91906124dc565b60405180910390f35b6102c260048036038101906102bd91906123f7565b610942565b005b6102de60048036038101906102d9919061221f565b610a88565b6040516102eb9190612168565b60405180910390f35b61030e6004803603810190610309919061221f565b610ac5565b005b610318610bce565b60405161032b9796959493929190612620565b60405180910390f35b61034e600480360381019061034991906124f5565b610c73565b60405161035b9190612168565b60405180910390f35b61037e600480360381019061037991906126a2565b610ca6565b005b61039a600480360381019061039591906128d4565b610fd6565b6040516103a79190612168565b60405180910390f35b6103ca60048036038101906103c5919061292e565b61122d565b6040516103d79190612168565b60405180910390f35b6103fa60048036038101906103f59190612975565b611478565b6040516104079190612168565b60405180910390f35b60606040518060400160405280600381526020017f41434c00000000000000000000000000000000000000000000000000000000008152506104515f611617565b61045b6001611617565b6104645f611617565b6040516020016104779493929190612aa7565b604051602081830303815290604052905090565b5f6001905090565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461051757336040517f3809a24300000000000000000000000000000000000000000000000000000000815260040161050e91906124dc565b60405180910390fd5b5f5c5f5f5d6001810160015b8181101561053f57805c5f825d5f815d50600181019050610523565b505050565b5f5f61054e6116e1565b9050806001015f8581526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1691505092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461063857336040517f3809a24300000000000000000000000000000000000000000000000000000000815260040161062f91906124dc565b60405180910390fd5b5f825190505f6106466116e1565b90505f5f90505b828110156106f7575f85828151811061066957610668612b05565b5b6020026020010151905061067d81866108bf565b6106be57846040517fd0d259760000000000000000000000000000000000000000000000000000000081526004016106b591906124dc565b60405180910390fd5b6001836002015f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555050808060010191505061064d565b507f2fd616621b8415a2efb27b224024340ac767797553ce6fdf4c1adefd160504c6846040516107279190612b32565b60405180910390a150505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107b957336040517f3809a2430000000000000000000000000000000000000000000000000000000081526004016107b091906124dc565b60405180910390fd5b6107c383826108bf565b158015610810575073ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1561085257806040517fd0d2597600000000000000000000000000000000000000000000000000000000815260040161084991906124dc565b60405180910390fd5b5f8383604051602001610866929190612bb7565b6040516020818303038152906040528051906020012090506001815d5f5c6001810182815d805f5d505050505050565b5f6108a082611747565b9050919050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d981565b5f6108ca8383610a88565b806108db57506108da8383610544565b5b806108eb57506108ea83610c73565b5b905092915050565b5f5f6108fd6116e1565b9050806002015f8481526020019081526020015f205f9054906101000a900460ff16915050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d9905090565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109c657336040517f3809a2430000000000000000000000000000000000000000000000000000000081526004016109bd91906124dc565b60405180910390fd5b6109d083826108bf565b610a1157806040517fd0d25976000000000000000000000000000000000000000000000000000000008152600401610a0891906124dc565b60405180910390fd5b5f610a1a6116e1565b90506001816001015f8681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050505050565b5f5f5f8484604051602001610a9e929190612bb7565b604051602081830303815290604052805190602001209050805c9150819250505092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4957336040517f3809a243000000000000000000000000000000000000000000000000000000008152600401610b4091906124dc565b60405180910390fd5b610b5382826108bf565b610b9457806040517fd0d25976000000000000000000000000000000000000000000000000000000008152600401610b8b91906124dc565b60405180910390fd5b5f610b9d6116e1565b90506001815f015f8581526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b5f6060805f5f5f6060610bdf611760565b610be761179a565b46305f5f1b5f67ffffffffffffffff811115610c0657610c05612261565b5b604051908082528060200260200182016040528015610c345781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f5f610c7d6116e1565b9050805f015f8481526020019081526020015f205f9054906101000a900460ff16915050919050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d2a57336040517f3809a243000000000000000000000000000000000000000000000000000000008152600401610d2191906124dc565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d8f576040517f30dc920300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610d986116e1565b9050806003015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615610e93576040517fd186046800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816003015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff03b7c0d4879b0bcbbf440794871f139c96fd13a145a8172b33b9cab5fa2830a60405160405180910390a4505050565b5f8242816020015167ffffffffffffffff161015611020576040517fed0764a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611042815f0151611038611033846117d5565b611747565b8360c0015161182e565b611078576040517f4c40eccb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16141580156110d857506110d681604001516110cc6110c7846118da565b611747565b8360e0015161182e565b155b1561110f576040517f8e143bf700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81606001511415801561115357505f73ffffffffffffffffffffffffffffffffffffffff16816080015173ffffffffffffffffffffffffffffffffffffffff1614155b80156111e05750806080015173ffffffffffffffffffffffffffffffffffffffff1663b63391e8825f015183606001516040518363ffffffff1660e01b81526004016111a0929190612be2565b602060405180830381865afa1580156111bb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111df9190612c33565b5b15611217576040517fcbd3a96600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61122483855f01516108bf565b91505092915050565b5f8142816020015167ffffffffffffffff161015611277576040517fed0764a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611299815f015161128f61128a846117d5565b611747565b8360c0015161182e565b6112cf576040517f4c40eccb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161415801561132f575061132d816040015161132361131e846118da565b611747565b8360e0015161182e565b155b15611366576040517f8e143bf700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8160600151141580156113aa57505f73ffffffffffffffffffffffffffffffffffffffff16816080015173ffffffffffffffffffffffffffffffffffffffff1614155b80156114375750806080015173ffffffffffffffffffffffffffffffffffffffff1663b63391e8825f015183606001516040518363ffffffff1660e01b81526004016113f7929190612be2565b602060405180830381865afa158015611412573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114369190612c33565b5b1561146e576040517fcbd3a96600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001915050919050565b5f5f6114826116e1565b9050806001015f8681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1680156115425750806001015f8681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b801561160c5750806003015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b915050949350505050565b60605f60016116258461193c565b0190505f8167ffffffffffffffff81111561164357611642612261565b5b6040519080825280601f01601f1916602001820160405280156116755781602001600182028036833780820191505090505b5090505f82602083010190505b6001156116d6578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816116cb576116ca612c5e565b5b0494505f8503611682575b819350505050919050565b5f5f60ff5f1b1960017fc4eb438ffad04c606bb4f9c3576c0f142d5dc3782731029ea1ab95b6483220115f1c6117179190612cb8565b6040516020016117279190612ceb565b604051602081830303815290604052805190602001201690508091505090565b5f611759611753611a8d565b83611b43565b9050919050565b60606117955f7f0000000000000000000000000000000000000000000000000000000000000000611b8390919063ffffffff16565b905090565b60606117d060017f0000000000000000000000000000000000000000000000000000000000000000611b8390919063ffffffff16565b905090565b5f5f73ffffffffffffffffffffffffffffffffffffffff16826040015173ffffffffffffffffffffffffffffffffffffffff160361181d5761181682611c30565b9050611829565b61182682611ca2565b90505b919050565b5f5f8473ffffffffffffffffffffffffffffffffffffffff163b036118c5575f5f6118598585611d0e565b50915091505f600381111561187157611870612d04565b5b81600381111561188457611883612d04565b5b1480156118bc57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b925050506118d3565b6118d0848484611d63565b90505b9392505050565b5f7f82af07a6c9eb6bb31a0c86f7f5cad0039589750ad5b4b925ed5741f7ad4e8d4b8260a001518360c001518051906020012060405160200161191f93929190612d31565b604051602081830303815290604052805190602001209050919050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611998577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161198e5761198d612c5e565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106119d5576d04ee2d6d415b85acef810000000083816119cb576119ca612c5e565b5b0492506020810190505b662386f26fc100008310611a0457662386f26fc1000083816119fa576119f9612c5e565b5b0492506010810190505b6305f5e1008310611a2d576305f5e1008381611a2357611a22612c5e565b5b0492506008810190505b6127108310611a52576127108381611a4857611a47612c5e565b5b0492506004810190505b60648310611a755760648381611a6b57611a6a612c5e565b5b0492506002810190505b600a8310611a84576001810190505b80915050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611b0857507f000000000000000000000000000000000000000000000000000000000000000046145b15611b35577f00000000000000000000000000000000000000000000000000000000000000009050611b40565b611b3d611e82565b90505b90565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b606060ff5f1b8314611b9f57611b9883611f17565b9050611c2a565b818054611bab90612d93565b80601f0160208091040260200160405190810160405280929190818152602001828054611bd790612d93565b8015611c225780601f10611bf957610100808354040283529160200191611c22565b820191905f5260205f20905b815481529060010190602001808311611c0557829003601f168201915b505050505090505b92915050565b5f7f0ce0d938c38f948b8f9cf16098cd15ec62de132c8d422719ad270c5e2a101102825f015183602001518460400151856060015186608001518760a00151604051602001611c859796959493929190612dd2565b604051602081830303815290604052805190602001209050919050565b5f7f8549e986c64faf9b741179c61561f9d39f337cf9739f86178d84dabc6ca4cad5825f01518360200151846040015185606001518660800151604051602001611cf196959493929190612e3f565b604051602081830303815290604052805190602001209050919050565b5f5f5f6041845103611d4e575f5f5f602087015192506040870151915060608701515f1a9050611d4088828585611f89565b955095509550505050611d5c565b5f600285515f1b9250925092505b9250925092565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff168585604051602401611d90929190612ef0565b604051602081830303815290604052631626ba7e60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611de29190612f58565b5f60405180830381855afa9150503d805f8114611e1a576040519150601f19603f3d011682016040523d82523d5f602084013e611e1f565b606091505b5091509150818015611e3357506020815110155b8015611e775750631626ba7e60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681806020019051810190611e759190612f82565b145b925050509392505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000004630604051602001611efc959493929190612fad565b60405160208183030381529060405280519060200120905090565b60605f611f2383612070565b90505f602067ffffffffffffffff811115611f4157611f40612261565b5b6040519080825280601f01601f191660200182016040528015611f735781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115611fc5575f600385925092509250612066565b5f6001888888886040515f8152602001604052604051611fe89493929190613019565b6020604051602081039080840390855afa158015612008573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612059575f60015f5f1b93509350935050612066565b805f5f5f1b935093509350505b9450945094915050565b5f5f60ff835f1c169050601f8111156120b5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612100826120be565b61210a81856120c8565b935061211a8185602086016120d8565b612123816120e6565b840191505092915050565b5f6020820190508181035f83015261214681846120f6565b905092915050565b5f8115159050919050565b6121628161214e565b82525050565b5f60208201905061217b5f830184612159565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b6121a481612192565b81146121ae575f5ffd5b50565b5f813590506121bf8161219b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6121ee826121c5565b9050919050565b6121fe816121e4565b8114612208575f5ffd5b50565b5f81359050612219816121f5565b92915050565b5f5f604083850312156122355761223461218a565b5b5f612242858286016121b1565b92505060206122538582860161220b565b9150509250929050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612297826120e6565b810181811067ffffffffffffffff821117156122b6576122b5612261565b5b80604052505050565b5f6122c8612181565b90506122d4828261228e565b919050565b5f67ffffffffffffffff8211156122f3576122f2612261565b5b602082029050602081019050919050565b5f5ffd5b5f61231a612315846122d9565b6122bf565b9050808382526020820190506020840283018581111561233d5761233c612304565b5b835b81811015612366578061235288826121b1565b84526020840193505060208101905061233f565b5050509392505050565b5f82601f8301126123845761238361225d565b5b8135612394848260208601612308565b91505092915050565b5f5f604083850312156123b3576123b261218a565b5b5f83013567ffffffffffffffff8111156123d0576123cf61218e565b5b6123dc85828601612370565b92505060206123ed8582860161220b565b9150509250929050565b5f5f5f6060848603121561240e5761240d61218a565b5b5f61241b868287016121b1565b935050602061242c8682870161220b565b925050604061243d8682870161220b565b9150509250925092565b5f819050919050565b61245981612447565b8114612463575f5ffd5b50565b5f8135905061247481612450565b92915050565b5f6020828403121561248f5761248e61218a565b5b5f61249c84828501612466565b91505092915050565b6124ae81612447565b82525050565b5f6020820190506124c75f8301846124a5565b92915050565b6124d6816121e4565b82525050565b5f6020820190506124ef5f8301846124cd565b92915050565b5f6020828403121561250a5761250961218a565b5b5f612517848285016121b1565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61255481612520565b82525050565b61256381612192565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61259b81612192565b82525050565b5f6125ac8383612592565b60208301905092915050565b5f602082019050919050565b5f6125ce82612569565b6125d88185612573565b93506125e383612583565b805f5b838110156126135781516125fa88826125a1565b9750612605836125b8565b9250506001810190506125e6565b5085935050505092915050565b5f60e0820190506126335f83018a61254b565b818103602083015261264581896120f6565b9050818103604083015261265981886120f6565b9050612668606083018761255a565b61267560808301866124cd565b61268260a08301856124a5565b81810360c083015261269481846125c4565b905098975050505050505050565b5f5f604083850312156126b8576126b761218a565b5b5f6126c58582860161220b565b92505060206126d68582860161220b565b9150509250929050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82169050919050565b612704816126e8565b811461270e575f5ffd5b50565b5f8135905061271f816126fb565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561274357612742612261565b5b61274c826120e6565b9050602081019050919050565b828183375f83830152505050565b5f61277961277484612729565b6122bf565b90508281526020810184848401111561279557612794612725565b5b6127a0848285612759565b509392505050565b5f82601f8301126127bc576127bb61225d565b5b81356127cc848260208601612767565b91505092915050565b5f61010082840312156127eb576127ea6126e0565b5b6127f66101006122bf565b90505f6128058482850161220b565b5f83015250602061281884828501612711565b602083015250604061282c8482850161220b565b6040830152506060612840848285016121b1565b60608301525060806128548482850161220b565b60808301525060a061286884828501612466565b60a08301525060c082013567ffffffffffffffff81111561288c5761288b6126e4565b5b612898848285016127a8565b60c08301525060e082013567ffffffffffffffff8111156128bc576128bb6126e4565b5b6128c8848285016127a8565b60e08301525092915050565b5f5f604083850312156128ea576128e961218a565b5b5f83013567ffffffffffffffff8111156129075761290661218e565b5b612913858286016127d5565b9250506020612924858286016121b1565b9150509250929050565b5f602082840312156129435761294261218a565b5b5f82013567ffffffffffffffff8111156129605761295f61218e565b5b61296c848285016127d5565b91505092915050565b5f5f5f5f6080858703121561298d5761298c61218a565b5b5f61299a8782880161220b565b94505060206129ab878288016121b1565b93505060406129bc8782880161220b565b92505060606129cd8782880161220b565b91505092959194509250565b5f81905092915050565b5f6129ed826120be565b6129f781856129d9565b9350612a078185602086016120d8565b80840191505092915050565b7f20760000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a476002836129d9565b9150612a5282612a13565b600282019050919050565b7f2e000000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a916001836129d9565b9150612a9c82612a5d565b600182019050919050565b5f612ab282876129e3565b9150612abd82612a3b565b9150612ac982866129e3565b9150612ad482612a85565b9150612ae082856129e3565b9150612aeb82612a85565b9150612af782846129e3565b915081905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6020820190508181035f830152612b4a81846125c4565b905092915050565b5f819050919050565b612b6c612b6782612192565b612b52565b82525050565b5f8160601b9050919050565b5f612b8882612b72565b9050919050565b5f612b9982612b7e565b9050919050565b612bb1612bac826121e4565b612b8f565b82525050565b5f612bc28285612b5b565b602082019150612bd28284612ba0565b6014820191508190509392505050565b5f604082019050612bf55f8301856124cd565b612c02602083018461255a565b9392505050565b612c128161214e565b8114612c1c575f5ffd5b50565b5f81519050612c2d81612c09565b92915050565b5f60208284031215612c4857612c4761218a565b5b5f612c5584828501612c1f565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612cc282612192565b9150612ccd83612192565b9250828203905081811115612ce557612ce4612c8b565b5b92915050565b5f602082019050612cfe5f83018461255a565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f606082019050612d445f8301866124a5565b612d5160208301856124a5565b612d5e60408301846124a5565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612daa57607f821691505b602082108103612dbd57612dbc612d66565b5b50919050565b612dcc816126e8565b82525050565b5f60e082019050612de55f83018a6124a5565b612df260208301896124cd565b612dff6040830188612dc3565b612e0c60608301876124cd565b612e19608083018661255a565b612e2660a08301856124cd565b612e3360c08301846124a5565b98975050505050505050565b5f60c082019050612e525f8301896124a5565b612e5f60208301886124cd565b612e6c6040830187612dc3565b612e7960608301866124cd565b612e86608083018561255a565b612e9360a08301846124cd565b979650505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f612ec282612e9e565b612ecc8185612ea8565b9350612edc8185602086016120d8565b612ee5816120e6565b840191505092915050565b5f604082019050612f035f8301856124a5565b8181036020830152612f158184612eb8565b90509392505050565b5f81905092915050565b5f612f3282612e9e565b612f3c8185612f1e565b9350612f4c8185602086016120d8565b80840191505092915050565b5f612f638284612f28565b915081905092915050565b5f81519050612f7c81612450565b92915050565b5f60208284031215612f9757612f9661218a565b5b5f612fa484828501612f6e565b91505092915050565b5f60a082019050612fc05f8301886124a5565b612fcd60208301876124a5565b612fda60408301866124a5565b612fe7606083018561255a565b612ff460808301846124cd565b9695505050505050565b5f60ff82169050919050565b61301381612ffe565b82525050565b5f60808201905061302c5f8301876124a5565b613039602083018661300a565b61304660408301856124a5565b61305360608301846124a5565b9594505050505056fea2646970667358221220955d41fe64344b5fe722f8d6f8f97e804a07610f7f4000f42fe11262e906158c64736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/MockQueryDecrypter.ts b/packages/mock-contracts/src/MockQueryDecrypter.ts index 4c41479d..db1ef416 100644 --- a/packages/mock-contracts/src/MockQueryDecrypter.ts +++ b/packages/mock-contracts/src/MockQueryDecrypter.ts @@ -348,5 +348,5 @@ export const MockQueryDecrypterArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b506004361061009c575f3560e01c80637e0f4b5b116100645780637e0f4b5b1461015a5780638a5c8c7f14610178578063a02eb534146101a8578063a0639f54146101da578063ff6957d31461020c5761009c565b806309ba3156146100a05780631a1992a9146100d2578063267c4ae414610102578063485cc955146101205780634cdc014d1461013c575b5f5ffd5b6100ba60048036038101906100b591906110b5565b61023c565b6040516100c9939291906111aa565b60405180910390f35b6100ec60048036038101906100e791906111e6565b61051f565b6040516100f99190611224565b60405180910390f35b61010a61052d565b604051610117919061123d565b60405180910390f35b61013a60048036038101906101359190611256565b610535565b005b6101446105b8565b60405161015191906112ef565b60405180910390f35b6101626105dd565b60405161016f9190611328565b60405180910390f35b610192600480360381019061018d9190611341565b610601565b60405161019f919061138e565b60405180910390f35b6101c260048036038101906101bd91906113a7565b61060f565b6040516101d1939291906113f7565b60405180910390f35b6101f460048036038101906101ef91906110b5565b61089e565b604051610203939291906113f7565b60405180910390f35b61022660048036038101906102219190611433565b610b28565b604051610233919061147a565b60405180910390f35b5f60605f5f5f1b8460a001510361027f576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016102dc9291906115dc565b602060405180830381865afa92505050801561031657506040513d601f19601f820116820180604052508101906103139190611634565b60015b6104025761032261166b565b806308c379a003610353575061033661168a565b8061034157506103b8565b5f815f5f1b9450945094505050610516565b634e487b71036103b857610365611719565b9061037057506103b8565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610516565b3d805f81146103e2576040519150601f19603f3d011682016040523d82523d5f602084013e6103e7565b606091505b505f6103f282610b28565b5f5f1b9450945094505050610516565b8091505080610452575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610516565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104ac919061138e565b602060405180830381865afa1580156104c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104eb919061174b565b905060016104fd828860a0015161051f565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b8152600401610670929190611785565b602060405180830381865afa9250505080156106aa57506040513d601f19601f820116820180604052508101906106a79190611634565b60015b610790576106b661166b565b806308c379a0036106e557506106ca61168a565b806106d55750610748565b5f815f9450945094505050610895565b634e487b7103610748576106f7611719565b906107025750610748565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610895565b3d805f8114610772576040519150601f19603f3d011682016040523d82523d5f602084013e610777565b606091505b505f61078282610b28565b5f9450945094505050610895565b80915050806107de575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610895565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610838919061138e565b602060405180830381865afa158015610853573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610877919061174b565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016108ff9291906115dc565b602060405180830381865afa92505050801561093957506040513d601f19601f820116820180604052508101906109369190611634565b60015b610a1f5761094561166b565b806308c379a003610974575061095961168a565b8061096457506109d7565b5f815f9450945094505050610b1f565b634e487b71036109d757610986611719565b9061099157506109d7565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b1f565b3d805f8114610a01576040519150601f19603f3d011682016040523d82523d5f602084013e610a06565b606091505b505f610a1182610b28565b5f9450945094505050610b1f565b8091505080610a6d575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b1f565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610ac8919061138e565b602060405180830381865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b07919061174b565b60405180602001604052805f81525090935093509350505b93509350939050565b60605f82610b3590611806565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bc1576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f4578706972656400000000000000815250915050610d5f565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c2e5760405180606001604052806021815260200161189160219139915050610d5f565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c9b5760405180606001604052806024815260200161186d60249139915050610d5f565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d25576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c6564000000000000815250915050610d5f565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610d8781610d75565b8114610d91575f5ffd5b50565b5f81359050610da281610d7e565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610df282610dac565b810181811067ffffffffffffffff82111715610e1157610e10610dbc565b5b80604052505050565b5f610e23610d64565b9050610e2f8282610de9565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6182610e38565b9050919050565b610e7181610e57565b8114610e7b575f5ffd5b50565b5f81359050610e8c81610e68565b92915050565b5f67ffffffffffffffff82169050919050565b610eae81610e92565b8114610eb8575f5ffd5b50565b5f81359050610ec981610ea5565b92915050565b5f819050919050565b610ee181610ecf565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115610f2457610f23610dbc565b5b610f2d82610dac565b9050602081019050919050565b828183375f83830152505050565b5f610f5a610f5584610f0a565b610e1a565b905082815260208101848484011115610f7657610f75610f06565b5b610f81848285610f3a565b509392505050565b5f82601f830112610f9d57610f9c610f02565b5b8135610fad848260208601610f48565b91505092915050565b5f6101008284031215610fcc57610fcb610da8565b5b610fd7610100610e1a565b90505f610fe684828501610e7e565b5f830152506020610ff984828501610ebb565b602083015250604061100d84828501610e7e565b604083015250606061102184828501610d94565b606083015250608061103584828501610e7e565b60808301525060a061104984828501610eee565b60a08301525060c082013567ffffffffffffffff81111561106d5761106c610e34565b5b61107984828501610f89565b60c08301525060e082013567ffffffffffffffff81111561109d5761109c610e34565b5b6110a984828501610f89565b60e08301525092915050565b5f5f5f606084860312156110cc576110cb610d6d565b5b5f6110d986828701610d94565b93505060206110ea86828701610d94565b925050604084013567ffffffffffffffff81111561110b5761110a610d71565b5b61111786828701610fb6565b9150509250925092565b5f8115159050919050565b61113581611121565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61116d8261113b565b6111778185611145565b9350611187818560208601611155565b61119081610dac565b840191505092915050565b6111a481610ecf565b82525050565b5f6060820190506111bd5f83018661112c565b81810360208301526111cf8185611163565b90506111de604083018461119b565b949350505050565b5f5f604083850312156111fc576111fb610d6d565b5b5f61120985828601610d94565b925050602061121a85828601610eee565b9150509250929050565b5f6020820190506112375f83018461119b565b92915050565b5f6020820190506112505f83018461112c565b92915050565b5f5f6040838503121561126c5761126b610d6d565b5b5f61127985828601610e7e565b925050602061128a85828601610e7e565b9150509250929050565b5f819050919050565b5f6112b76112b26112ad84610e38565b611294565b610e38565b9050919050565b5f6112c88261129d565b9050919050565b5f6112d9826112be565b9050919050565b6112e9816112cf565b82525050565b5f6020820190506113025f8301846112e0565b92915050565b5f611312826112be565b9050919050565b61132281611308565b82525050565b5f60208201905061133b5f830184611319565b92915050565b5f5f6040838503121561135757611356610d6d565b5b5f61136485828601610eee565b925050602061137585828601610eee565b9150509250929050565b61138881610d75565b82525050565b5f6020820190506113a15f83018461137f565b92915050565b5f5f5f606084860312156113be576113bd610d6d565b5b5f6113cb86828701610d94565b93505060206113dc86828701610d94565b92505060406113ed86828701610e7e565b9150509250925092565b5f60608201905061140a5f83018661112c565b818103602083015261141c8185611163565b905061142b604083018461137f565b949350505050565b5f6020828403121561144857611447610d6d565b5b5f82013567ffffffffffffffff81111561146557611464610d71565b5b61147184828501610f89565b91505092915050565b5f6020820190508181035f8301526114928184611163565b905092915050565b6114a381610e57565b82525050565b6114b281610e92565b82525050565b6114c181610d75565b82525050565b6114d081610ecf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6114fa826114d6565b61150481856114e0565b9350611514818560208601611155565b61151d81610dac565b840191505092915050565b5f61010083015f83015161153e5f86018261149a565b50602083015161155160208601826114a9565b506040830151611564604086018261149a565b50606083015161157760608601826114b8565b50608083015161158a608086018261149a565b5060a083015161159d60a08601826114c7565b5060c083015184820360c08601526115b582826114f0565b91505060e083015184820360e08601526115cf82826114f0565b9150508091505092915050565b5f6040820190508181035f8301526115f48185611528565b9050611603602083018461137f565b9392505050565b61161381611121565b811461161d575f5ffd5b50565b5f8151905061162e8161160a565b92915050565b5f6020828403121561164957611648610d6d565b5b5f61165684828501611620565b91505092915050565b5f8160e01c9050919050565b5f60033d11156116875760045f5f3e6116845f5161165f565b90505b90565b5f60443d106117165761169b610d64565b60043d036004823e80513d602482011167ffffffffffffffff821117156116c3575050611716565b808201805167ffffffffffffffff8111156116e15750505050611716565b80602083010160043d0385018111156116fe575050505050611716565b61170d82602001850186610de9565b82955050505050505b90565b5f5f60233d111561173357602060045f3e600191505f5190505b9091565b5f8151905061174581610d7e565b92915050565b5f602082840312156117605761175f610d6d565b5b5f61176d84828501611737565b91505092915050565b61177f81610e57565b82525050565b5f6040820190506117985f83018561137f565b6117a56020830184611776565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f6117f182516117bb565b80915050919050565b5f82821b905092915050565b5f611810826114d6565b8261181a846117ac565b9050611825816117e6565b92506004821015611865576118607fffffffff00000000000000000000000000000000000000000000000000000000836004036008026117fa565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220ea7aaacf8df597acf06d11b043b93f49496ae268dcfd4e421962c00a017689f664736f6c63430008210033', + '0x608060405234801561000f575f5ffd5b506004361061009c575f3560e01c80637e0f4b5b116100645780637e0f4b5b1461015a5780638a5c8c7f14610178578063a02eb534146101a8578063a0639f54146101da578063ff6957d31461020c5761009c565b806309ba3156146100a05780631a1992a9146100d2578063267c4ae414610102578063485cc955146101205780634cdc014d1461013c575b5f5ffd5b6100ba60048036038101906100b591906110b5565b61023c565b6040516100c9939291906111aa565b60405180910390f35b6100ec60048036038101906100e791906111e6565b61051f565b6040516100f99190611224565b60405180910390f35b61010a61052d565b604051610117919061123d565b60405180910390f35b61013a60048036038101906101359190611256565b610535565b005b6101446105b8565b60405161015191906112ef565b60405180910390f35b6101626105dd565b60405161016f9190611328565b60405180910390f35b610192600480360381019061018d9190611341565b610601565b60405161019f919061138e565b60405180910390f35b6101c260048036038101906101bd91906113a7565b61060f565b6040516101d1939291906113f7565b60405180910390f35b6101f460048036038101906101ef91906110b5565b61089e565b604051610203939291906113f7565b60405180910390f35b61022660048036038101906102219190611433565b610b28565b604051610233919061147a565b60405180910390f35b5f60605f5f5f1b8460a001510361027f576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016102dc9291906115dc565b602060405180830381865afa92505050801561031657506040513d601f19601f820116820180604052508101906103139190611634565b60015b6104025761032261166b565b806308c379a003610353575061033661168a565b8061034157506103b8565b5f815f5f1b9450945094505050610516565b634e487b71036103b857610365611719565b9061037057506103b8565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610516565b3d805f81146103e2576040519150601f19603f3d011682016040523d82523d5f602084013e6103e7565b606091505b505f6103f282610b28565b5f5f1b9450945094505050610516565b8091505080610452575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610516565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104ac919061138e565b602060405180830381865afa1580156104c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104eb919061174b565b905060016104fd828860a0015161051f565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b8152600401610670929190611785565b602060405180830381865afa9250505080156106aa57506040513d601f19601f820116820180604052508101906106a79190611634565b60015b610790576106b661166b565b806308c379a0036106e557506106ca61168a565b806106d55750610748565b5f815f9450945094505050610895565b634e487b7103610748576106f7611719565b906107025750610748565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610895565b3d805f8114610772576040519150601f19603f3d011682016040523d82523d5f602084013e610777565b606091505b505f61078282610b28565b5f9450945094505050610895565b80915050806107de575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610895565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610838919061138e565b602060405180830381865afa158015610853573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610877919061174b565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016108ff9291906115dc565b602060405180830381865afa92505050801561093957506040513d601f19601f820116820180604052508101906109369190611634565b60015b610a1f5761094561166b565b806308c379a003610974575061095961168a565b8061096457506109d7565b5f815f9450945094505050610b1f565b634e487b71036109d757610986611719565b9061099157506109d7565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b1f565b3d805f8114610a01576040519150601f19603f3d011682016040523d82523d5f602084013e610a06565b606091505b505f610a1182610b28565b5f9450945094505050610b1f565b8091505080610a6d575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b1f565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610ac8919061138e565b602060405180830381865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b07919061174b565b60405180602001604052805f81525090935093509350505b93509350939050565b60605f82610b3590611806565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bc1576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f4578706972656400000000000000815250915050610d5f565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c2e5760405180606001604052806021815260200161189160219139915050610d5f565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c9b5760405180606001604052806024815260200161186d60249139915050610d5f565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d25576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c6564000000000000815250915050610d5f565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610d8781610d75565b8114610d91575f5ffd5b50565b5f81359050610da281610d7e565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610df282610dac565b810181811067ffffffffffffffff82111715610e1157610e10610dbc565b5b80604052505050565b5f610e23610d64565b9050610e2f8282610de9565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6182610e38565b9050919050565b610e7181610e57565b8114610e7b575f5ffd5b50565b5f81359050610e8c81610e68565b92915050565b5f67ffffffffffffffff82169050919050565b610eae81610e92565b8114610eb8575f5ffd5b50565b5f81359050610ec981610ea5565b92915050565b5f819050919050565b610ee181610ecf565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115610f2457610f23610dbc565b5b610f2d82610dac565b9050602081019050919050565b828183375f83830152505050565b5f610f5a610f5584610f0a565b610e1a565b905082815260208101848484011115610f7657610f75610f06565b5b610f81848285610f3a565b509392505050565b5f82601f830112610f9d57610f9c610f02565b5b8135610fad848260208601610f48565b91505092915050565b5f6101008284031215610fcc57610fcb610da8565b5b610fd7610100610e1a565b90505f610fe684828501610e7e565b5f830152506020610ff984828501610ebb565b602083015250604061100d84828501610e7e565b604083015250606061102184828501610d94565b606083015250608061103584828501610e7e565b60808301525060a061104984828501610eee565b60a08301525060c082013567ffffffffffffffff81111561106d5761106c610e34565b5b61107984828501610f89565b60c08301525060e082013567ffffffffffffffff81111561109d5761109c610e34565b5b6110a984828501610f89565b60e08301525092915050565b5f5f5f606084860312156110cc576110cb610d6d565b5b5f6110d986828701610d94565b93505060206110ea86828701610d94565b925050604084013567ffffffffffffffff81111561110b5761110a610d71565b5b61111786828701610fb6565b9150509250925092565b5f8115159050919050565b61113581611121565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61116d8261113b565b6111778185611145565b9350611187818560208601611155565b61119081610dac565b840191505092915050565b6111a481610ecf565b82525050565b5f6060820190506111bd5f83018661112c565b81810360208301526111cf8185611163565b90506111de604083018461119b565b949350505050565b5f5f604083850312156111fc576111fb610d6d565b5b5f61120985828601610d94565b925050602061121a85828601610eee565b9150509250929050565b5f6020820190506112375f83018461119b565b92915050565b5f6020820190506112505f83018461112c565b92915050565b5f5f6040838503121561126c5761126b610d6d565b5b5f61127985828601610e7e565b925050602061128a85828601610e7e565b9150509250929050565b5f819050919050565b5f6112b76112b26112ad84610e38565b611294565b610e38565b9050919050565b5f6112c88261129d565b9050919050565b5f6112d9826112be565b9050919050565b6112e9816112cf565b82525050565b5f6020820190506113025f8301846112e0565b92915050565b5f611312826112be565b9050919050565b61132281611308565b82525050565b5f60208201905061133b5f830184611319565b92915050565b5f5f6040838503121561135757611356610d6d565b5b5f61136485828601610eee565b925050602061137585828601610eee565b9150509250929050565b61138881610d75565b82525050565b5f6020820190506113a15f83018461137f565b92915050565b5f5f5f606084860312156113be576113bd610d6d565b5b5f6113cb86828701610d94565b93505060206113dc86828701610d94565b92505060406113ed86828701610e7e565b9150509250925092565b5f60608201905061140a5f83018661112c565b818103602083015261141c8185611163565b905061142b604083018461137f565b949350505050565b5f6020828403121561144857611447610d6d565b5b5f82013567ffffffffffffffff81111561146557611464610d71565b5b61147184828501610f89565b91505092915050565b5f6020820190508181035f8301526114928184611163565b905092915050565b6114a381610e57565b82525050565b6114b281610e92565b82525050565b6114c181610d75565b82525050565b6114d081610ecf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6114fa826114d6565b61150481856114e0565b9350611514818560208601611155565b61151d81610dac565b840191505092915050565b5f61010083015f83015161153e5f86018261149a565b50602083015161155160208601826114a9565b506040830151611564604086018261149a565b50606083015161157760608601826114b8565b50608083015161158a608086018261149a565b5060a083015161159d60a08601826114c7565b5060c083015184820360c08601526115b582826114f0565b91505060e083015184820360e08601526115cf82826114f0565b9150508091505092915050565b5f6040820190508181035f8301526115f48185611528565b9050611603602083018461137f565b9392505050565b61161381611121565b811461161d575f5ffd5b50565b5f8151905061162e8161160a565b92915050565b5f6020828403121561164957611648610d6d565b5b5f61165684828501611620565b91505092915050565b5f8160e01c9050919050565b5f60033d11156116875760045f5f3e6116845f5161165f565b90505b90565b5f60443d106117165761169b610d64565b60043d036004823e80513d602482011167ffffffffffffffff821117156116c3575050611716565b808201805167ffffffffffffffff8111156116e15750505050611716565b80602083010160043d0385018111156116fe575050505050611716565b61170d82602001850186610de9565b82955050505050505b90565b5f5f60233d111561173357602060045f3e600191505f5190505b9091565b5f8151905061174581610d7e565b92915050565b5f602082840312156117605761175f610d6d565b5b5f61176d84828501611737565b91505092915050565b61177f81610e57565b82525050565b5f6040820190506117985f83018561137f565b6117a56020830184611776565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f6117f182516117bb565b80915050919050565b5f82821b905092915050565b5f611810826114d6565b8261181a846117ac565b9050611825816117e6565b92506004821015611865576118607fffffffff00000000000000000000000000000000000000000000000000000000836004036008026117fa565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220fd8e9a6aa7147960d4cd0eebd7d8331bb5cbbe3b6c8809265fe5db60d8f91d3b64736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/MockTaskManager.ts b/packages/mock-contracts/src/MockTaskManager.ts index b949f92f..0a929b42 100644 --- a/packages/mock-contracts/src/MockTaskManager.ts +++ b/packages/mock-contracts/src/MockTaskManager.ts @@ -158,6 +158,35 @@ export const MockTaskManagerArtifact = { outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + name: 'createRandomTask', + inputs: [ + { + name: 'returnType', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'seed', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'securityZone', + type: 'int32', + internalType: 'int32', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, { type: 'function', name: 'createTask', @@ -192,6 +221,19 @@ export const MockTaskManagerArtifact = { ], stateMutability: 'nonpayable', }, + { + type: 'function', + name: 'decryptResultSigner', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, { type: 'function', name: 'exists', @@ -429,6 +471,25 @@ export const MockTaskManagerArtifact = { ], stateMutability: 'view', }, + { + type: 'function', + name: 'isPubliclyAllowed', + inputs: [ + { + name: 'ctHash', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, { type: 'function', name: 'logOps', @@ -461,6 +522,52 @@ export const MockTaskManagerArtifact = { ], stateMutability: 'view', }, + { + type: 'function', + name: 'publishDecryptResult', + inputs: [ + { + name: 'ctHash', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'result', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'publishDecryptResultBatch', + inputs: [ + { + name: 'ctHashes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'results', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signatures', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', name: 'removeFirstLetter', @@ -506,6 +613,19 @@ export const MockTaskManagerArtifact = { outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + name: 'setDecryptResultSigner', + inputs: [ + { + name: 'signer', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', name: 'setLogOps', @@ -605,6 +725,64 @@ export const MockTaskManagerArtifact = { ], stateMutability: 'pure', }, + { + type: 'function', + name: 'verifyDecryptResult', + inputs: [ + { + name: 'ctHash', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'result', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'verifyDecryptResultSafe', + inputs: [ + { + name: 'ctHash', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'result', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, { type: 'function', name: 'verifyInput', @@ -1024,5 +1202,5 @@ export const MockTaskManagerArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b50600436106101ee575f3560e01c8063642b3f191161010d578063a307d21d116100a0578063de2873591161006f578063de287359146105bd578063e68d826f146105db578063f6bc7f3f146105f9578063f9120af614610629576101ee565b8063a307d21d14610525578063ae79f04a14610541578063c4d66de814610571578063d521ed4b1461058d576101ee565b80638b2b9c23116100dc5780638b2b9c23146104b55780638d9c9c92146104d15780638db39c8d146104ed57806392bd6c9514610509576101ee565b8063642b3f191461043157806365d0509c1461044d5780637e5cf5191461046957806381ba098614610499576101ee565b806327f9c762116101855780634bc98263116101545780634bc98263146103ad578063591363c7146103c95780635faa299a146103e55780635fb0bf9114610415576101ee565b806327f9c7621461031257806334ef1e5a14610342578063392e53cd1461035e578063458693c91461037c576101ee565b80631d031931116101c15780631d0319311461028a578063245a7bfc146102ba57806326594a0c146102d8578063267c4ae4146102f4576101ee565b806308289827146101f257806315a486fe1461020e5780631888debd1461022a5780631c76642b1461025a575b5f5ffd5b61020c6004803603810190610207919061609e565b610645565b005b610228600480360381019061022391906160dc565b6106f8565b005b610244600480360381019061023f91906162c3565b610706565b604051610251919061636e565b60405180910390f35b610274600480360381019061026f9190616387565b6108aa565b604051610281919061636e565b60405180910390f35b6102a4600480360381019061029f9190616387565b6108bf565b6040516102b191906163cc565b60405180910390f35b6102c26108dc565b6040516102cf91906163f4565b60405180910390f35b6102f260048036038101906102ed9190616443565b610902565b005b6102fc6109de565b60405161030991906163cc565b60405180910390f35b61032c600480360381019061032791906165ca565b6109e6565b604051610339919061636e565b60405180910390f35b61035c60048036038101906103579190616387565b610c20565b005b610366610cfa565b60405161037391906163cc565b60405180910390f35b61039660048036038101906103919190616387565b610d10565b6040516103a4929190616624565b60405180910390f35b6103c760048036038101906103c291906166e9565b610d95565b005b6103e360048036038101906103de9190616771565b610e67565b005b6103ff60048036038101906103fa919061609e565b610f99565b60405161040c91906163cc565b60405180910390f35b61042f600480360381019061042a9190616771565b611055565b005b61044b600480360381019061044691906167c6565b611187565b005b6104676004803603810190610462919061609e565b6111a2565b005b610483600480360381019061047e91906167f1565b6112ee565b60405161049091906168bd565b60405180910390f35b6104b360048036038101906104ae9190616936565b611424565b005b6104cf60048036038101906104ca91906169a7565b611532565b005b6104eb60048036038101906104e6919061609e565b611542565b005b61050760048036038101906105029190616a13565b61161f565b005b610523600480360381019061051e9190616a13565b6116f3565b005b61053f600480360381019061053a9190616387565b61182c565b005b61055b60048036038101906105569190616bad565b611974565b60405161056891906163cc565b60405180910390f35b61058b60048036038101906105869190616a13565b611a18565b005b6105a760048036038101906105a29190616c07565b611ab6565b6040516105b491906168bd565b60405180910390f35b6105c5611bcb565b6040516105d29190616ca9565b60405180910390f35b6105e3611bf0565b6040516105f091906163cc565b60405180910390f35b610613600480360381019061060e9190616387565b611c01565b604051610620919061636e565b60405180910390f35b610643600480360381019061063e9190616a13565b611c5d565b005b61064e82611d97565b600160055f8481526020019081526020015f205f6101000a81548160ff02191690831515021790555061068082611e86565b60045f8481526020019081526020015f20819055505f6001600a426106a59190616cef565b6106af9190616d4c565b905080426106bd9190616d7f565b60065f8581526020019081526020015f205f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b6107028282611f0e565b5050565b5f601b601f81111561071b5761071a616dba565b5b84601f81111561072e5761072d616dba565b5b03610765576040517f98e08ab000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f825184516107749190616d4c565b905060038111156107c95761078885611f2c565b8160036040517f2b0399d50000000000000000000000000000000000000000000000000000000081526004016107c093929190616e20565b60405180910390fd5b6107d38486612ac1565b5f6107de8585612d3b565b90505f6107ec878787612e7d565b90505f6107fb8983858b612ee8565b905060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228233306040518463ffffffff1660e01b815260040161085b93929190616e5c565b5f604051808303815f87803b158015610872575f5ffd5b505af1158015610884573d5f5f3e3d5ffd5b5050505061089b816108958a611f2c565b8561306d565b80945050505050949350505050565b6001602052805f5260405f205f915090505481565b6002602052805f5260405f205f915054906101000a900460ff1681565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461099357336040517f7238ea5600000000000000000000000000000000000000000000000000000000815260040161098a91906163f4565b60405180910390fd5b81600760046101000a81548163ffffffff021916908360030b63ffffffff1602179055508060075f6101000a81548163ffffffff021916908360030b63ffffffff1602179055505050565b5f6001905090565b5f5f836020015160ff1690505f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b7457610a4f816132c2565b610ab15780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401610aa893929190616ea0565b60405180910390fd5b5f610abc8585613303565b905060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b72578060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f7ba5ffb5000000000000000000000000000000000000000000000000000000008152600401610b69929190616ed5565b60405180910390fd5b505b5f610b88855f01518387604001515f6133c7565b905060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228233306040518463ffffffff1660e01b8152600401610be893929190616e5c565b5f604051808303815f87803b158015610bff575f5ffd5b505af1158015610c11573d5f5f3e3d5ffd5b50505050809250505092915050565b610c2981613420565b610cf75760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663846cd43382336040518363ffffffff1660e01b8152600401610c89929190616efc565b5f604051808303815f87803b158015610ca0575f5ffd5b505af1158015610cb2573d5f5f3e3d5ffd5b50505050610cf66040518060400160405280600f81526020017f4648452e616c6c6f77476c6f62616c00000000000000000000000000000000008152508233611532565b5b50565b5f600360149054906101000a900460ff16905090565b5f5f60055f8481526020019081526020015f205f9054906101000a900460ff16610d3f575f5f91509150610d90565b60065f8481526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16421015610d80575f5f91509150610d90565b610d8983611e86565b6001915091505b915091565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e2757336040517fa974a0fe000000000000000000000000000000000000000000000000000000008152600401610e1e91906163f4565b60405180910390fd5b7f66d3f531abdf188fde59b6d2b282dc7c725ef2bb1c6c93954054721a13c1a3fa838383604051610e5a93929190616f23565b60405180910390a1505050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ef857336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401610eef91906163f4565b60405180910390fd5b600760049054906101000a900460030b60030b8160030b1215610f735780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401610f6a93929190616ea0565b60405180910390fd5b8060075f6101000a81548163ffffffff021916908360030b63ffffffff16021790555050565b5f610fa383613420565b15610fb1576001905061104f565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a84846040518363ffffffff1660e01b815260040161100d929190616efc565b602060405180830381865afa158015611028573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061104c9190616f7a565b90505b92915050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e657336040517f7238ea560000000000000000000000000000000000000000000000000000000081526004016110dd91906163f4565b60405180910390fd5b60075f9054906101000a900460030b60030b8160030b13156111605780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf3600000000000000000000000000000000000000000000000000000000815260040161115793929190616ea0565b60405180910390fd5b80600760046101000a81548163ffffffff021916908360030b63ffffffff16021790555050565b805f5f6101000a81548160ff02191690831515021790555050565b6111ab82613420565b6112ea5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379a3a7fb8383336040518463ffffffff1660e01b815260040161120d93929190616e5c565b5f604051808303815f87803b158015611224575f5ffd5b505af1158015611236573d5f5f3e3d5ffd5b505050506112e93373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146112ab576040518060400160405280600981526020017f4648452e616c6c6f7700000000000000000000000000000000000000000000008152506112e2565b6040518060400160405280600d81526020017f4648452e616c6c6f7754686973000000000000000000000000000000000000008152505b8383611532565b5b5050565b60605f849050805183856113029190616d4c565b1115611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a90616fef565b60405180910390fd5b5f8367ffffffffffffffff81111561135e5761135d616187565b5b6040519080825280601f01601f1916602001820160405280156113905781602001600182028036833780820191505090505b5090505f5f90505b84811015611417578281876113ad9190616d4c565b815181106113be576113bd61700d565b5b602001015160f81c60f81b8282815181106113dc576113db61700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050611398565b5080925050509392505050565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114b657336040517fa974a0fe0000000000000000000000000000000000000000000000000000000081526004016114ad91906163f4565b60405180910390fd5b600160055f8681526020019081526020015f205f6101000a81548160ff0219169083151502179055508260045f8681526020019081526020015f20819055504260065f8681526020019081526020015f205f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050505050565b61153d83838361345d565b505050565b61154b82613420565b61161b5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228383336040518463ffffffff1660e01b81526004016115ad93929190616e5c565b5f604051808303815f87803b1580156115c4575f5ffd5b505af11580156115d6573d5f5f3e3d5ffd5b5050505061161a6040518060400160405280601281526020017f4648452e616c6c6f775472616e7369656e7400000000000000000000000000008152508383611532565b5b5050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116b057336040517f7238ea560000000000000000000000000000000000000000000000000000000081526004016116a791906163f4565b60405180910390fd5b8060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461178457336040517f7238ea5600000000000000000000000000000000000000000000000000000000815260040161177b91906163f4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036117e9576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61183581613420565b611971575f600167ffffffffffffffff81111561185557611854616187565b5b6040519080825280602002602001820160405280156118835781602001602082028036833780820191505090505b50905081815f8151811061189a5761189961700d565b5b60200260200101818152505060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c3839ba82336040518363ffffffff1660e01b81526004016119029291906170f1565b5f604051808303815f87803b158015611919575f5ffd5b505af115801561192b573d5f5f3e3d5ffd5b5050505061196f6040518060400160405280601681526020017f4648452e616c6c6f77466f7244656372797074696f6e000000000000000000008152508333611532565b505b50565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a84846040518363ffffffff1660e01b81526004016119d1929190617252565b602060405180830381865afa1580156119ec573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a109190616f7a565b905092915050565b8060035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600360146101000a81548160ff0219169083151502179055505f60095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f8290505f815103611adb5760405180602001604052805f815250915050611bc6565b5f60018251611aea9190617280565b67ffffffffffffffff811115611b0357611b02616187565b5b6040519080825280601f01601f191660200182016040528015611b355781602001600182028036833780820191505090505b5090505f600190505b8251811015611bbf57828181518110611b5a57611b5961700d565b5b602001015160f81c60f81b82600183611b739190617280565b81518110611b8457611b8361700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050611b3e565b5080925050505b919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900460ff1681565b5f5f5f611c0d84610d10565b9150915080611c5357836040517f70cf6554000000000000000000000000000000000000000000000000000000008152600401611c4a919061636e565b60405180910390fd5b8192505050919050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cee57336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401611ce591906163f4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d53576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611da081613420565b611e835760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a82336040518363ffffffff1660e01b8152600401611e00929190616efc565b602060405180830381865afa158015611e1b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e3f9190616f7a565b611e825780336040517f4d13139e000000000000000000000000000000000000000000000000000000008152600401611e79929190616efc565b60405180910390fd5b5b50565b5f60025f8381526020019081526020015f205f9054906101000a900460ff16611ee657816040517f850a796d000000000000000000000000000000000000000000000000000000008152600401611edd919061636e565b60405180910390fd5b5f611ef08361354b565b90508060015f8581526020019081526020015f205416915050919050565b5f611f188361354b565b9050611f27838284165f613568565b505050565b60606002601f811115611f4257611f41616dba565b5b82601f811115611f5557611f54616dba565b5b03611f97576040518060400160405280600481526020017f63617374000000000000000000000000000000000000000000000000000000008152509050612abc565b6003601f811115611fab57611faa616dba565b5b82601f811115611fbe57611fbd616dba565b5b03612000576040518060400160405280600a81526020017f7365616c4f7574707574000000000000000000000000000000000000000000008152509050612abc565b6004601f81111561201457612013616dba565b5b82601f81111561202757612026616dba565b5b03612069576040518060400160405280600681526020017f73656c65637400000000000000000000000000000000000000000000000000008152509050612abc565b6006601f81111561207d5761207c616dba565b5b82601f8111156120905761208f616dba565b5b036120d2576040518060400160405280600781526020017f64656372797074000000000000000000000000000000000000000000000000008152509050612abc565b6007601f8111156120e6576120e5616dba565b5b82601f8111156120f9576120f8616dba565b5b0361213b576040518060400160405280600381526020017f73756200000000000000000000000000000000000000000000000000000000008152509050612abc565b6008601f81111561214f5761214e616dba565b5b82601f81111561216257612161616dba565b5b036121a4576040518060400160405280600381526020017f61646400000000000000000000000000000000000000000000000000000000008152509050612abc565b6009601f8111156121b8576121b7616dba565b5b82601f8111156121cb576121ca616dba565b5b0361220d576040518060400160405280600381526020017f786f7200000000000000000000000000000000000000000000000000000000008152509050612abc565b600a601f81111561222157612220616dba565b5b82601f81111561223457612233616dba565b5b03612276576040518060400160405280600381526020017f616e6400000000000000000000000000000000000000000000000000000000008152509050612abc565b600b601f81111561228a57612289616dba565b5b82601f81111561229d5761229c616dba565b5b036122df576040518060400160405280600281526020017f6f720000000000000000000000000000000000000000000000000000000000008152509050612abc565b600c601f8111156122f3576122f2616dba565b5b82601f81111561230657612305616dba565b5b03612348576040518060400160405280600381526020017f6e6f7400000000000000000000000000000000000000000000000000000000008152509050612abc565b600d601f81111561235c5761235b616dba565b5b82601f81111561236f5761236e616dba565b5b036123b1576040518060400160405280600381526020017f64697600000000000000000000000000000000000000000000000000000000008152509050612abc565b600e601f8111156123c5576123c4616dba565b5b82601f8111156123d8576123d7616dba565b5b0361241a576040518060400160405280600381526020017f72656d00000000000000000000000000000000000000000000000000000000008152509050612abc565b600f601f81111561242e5761242d616dba565b5b82601f81111561244157612440616dba565b5b03612483576040518060400160405280600381526020017f6d756c00000000000000000000000000000000000000000000000000000000008152509050612abc565b6010601f81111561249757612496616dba565b5b82601f8111156124aa576124a9616dba565b5b036124ec576040518060400160405280600381526020017f73686c00000000000000000000000000000000000000000000000000000000008152509050612abc565b6011601f811115612500576124ff616dba565b5b82601f81111561251357612512616dba565b5b03612555576040518060400160405280600381526020017f73687200000000000000000000000000000000000000000000000000000000008152509050612abc565b6012601f81111561256957612568616dba565b5b82601f81111561257c5761257b616dba565b5b036125be576040518060400160405280600381526020017f67746500000000000000000000000000000000000000000000000000000000008152509050612abc565b6013601f8111156125d2576125d1616dba565b5b82601f8111156125e5576125e4616dba565b5b03612627576040518060400160405280600381526020017f6c746500000000000000000000000000000000000000000000000000000000008152509050612abc565b6014601f81111561263b5761263a616dba565b5b82601f81111561264e5761264d616dba565b5b03612690576040518060400160405280600281526020017f6c740000000000000000000000000000000000000000000000000000000000008152509050612abc565b6015601f8111156126a4576126a3616dba565b5b82601f8111156126b7576126b6616dba565b5b036126f9576040518060400160405280600281526020017f67740000000000000000000000000000000000000000000000000000000000008152509050612abc565b6016601f81111561270d5761270c616dba565b5b82601f8111156127205761271f616dba565b5b03612762576040518060400160405280600381526020017f6d696e00000000000000000000000000000000000000000000000000000000008152509050612abc565b6017601f81111561277657612775616dba565b5b82601f81111561278957612788616dba565b5b036127cb576040518060400160405280600381526020017f6d617800000000000000000000000000000000000000000000000000000000008152509050612abc565b6018601f8111156127df576127de616dba565b5b82601f8111156127f2576127f1616dba565b5b03612834576040518060400160405280600281526020017f65710000000000000000000000000000000000000000000000000000000000008152509050612abc565b6019601f81111561284857612847616dba565b5b82601f81111561285b5761285a616dba565b5b0361289d576040518060400160405280600281526020017f6e650000000000000000000000000000000000000000000000000000000000008152509050612abc565b601a601f8111156128b1576128b0616dba565b5b82601f8111156128c4576128c3616dba565b5b03612906576040518060400160405280600e81526020017f7472697669616c456e63727970740000000000000000000000000000000000008152509050612abc565b601b601f81111561291a57612919616dba565b5b82601f81111561292d5761292c616dba565b5b0361296f576040518060400160405280600681526020017f72616e646f6d00000000000000000000000000000000000000000000000000008152509050612abc565b601c601f81111561298357612982616dba565b5b82601f81111561299657612995616dba565b5b036129d8576040518060400160405280600381526020017f726f6c00000000000000000000000000000000000000000000000000000000008152509050612abc565b601d601f8111156129ec576129eb616dba565b5b82601f8111156129ff576129fe616dba565b5b03612a41576040518060400160405280600381526020017f726f7200000000000000000000000000000000000000000000000000000000008152509050612abc565b601e601f811115612a5557612a54616dba565b5b82601f811115612a6857612a67616dba565b5b03612aaa576040518060400160405280600681526020017f73717561726500000000000000000000000000000000000000000000000000008152509050612abc565b60405180602001604052805f81525090505b919050565b5f612acb82611f2c565b90505f835103612b2557612ade82613609565b612b1f57806040517fb31612aa000000000000000000000000000000000000000000000000000000008152600401612b1691906168bd565b60405180910390fd5b50612d37565b6004601f811115612b3957612b38616dba565b5b82601f811115612b4c57612b4b616dba565b5b03612b5f57612b5a83613668565b612c8f565b612b68826137a9565b15612bbe576001835114612bb95780835160016040517f9a84351c000000000000000000000000000000000000000000000000000000008152600401612bb0939291906172ec565b60405180910390fd5b612c8e565b6002835114612c0a5780835160026040517f9a84351c000000000000000000000000000000000000000000000000000000008152600401612c0193929190617361565b60405180910390fd5b5f612c4b84600181518110612c2257612c2161700d565b5b6020026020010151855f81518110612c3d57612c3c61700d565b5b602002602001015118613837565b14612c8d57806040517f52b50ae1000000000000000000000000000000000000000000000000000000008152600401612c8491906168bd565b60405180910390fd5b5b5b5f612cb3845f81518110612ca657612ca561700d565b5b6020026020010151613855565b9050612cbe816132c2565b612d205780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401612d1793929190616ea0565b60405180910390fd5b612d2984613865565b612d348383866138b3565b50505b5050565b60605f82518451612d4c9190616d4c565b67ffffffffffffffff811115612d6557612d64616187565b5b604051908082528060200260200182016040528015612d935781602001602082028036833780820191505090505b5090505f5f90505b84518160ff161015612dfa57848160ff1681518110612dbd57612dbc61700d565b5b6020026020010151828260ff1681518110612ddb57612dda61700d565b5b6020026020010181815250508080612df29061739d565b915050612d9b565b5b83518551612e099190616d4c565b8160ff161015612e72578385518260ff16612e249190617280565b81518110612e3557612e3461700d565b5b6020026020010151828260ff1681518110612e5357612e5261700d565b5b6020026020010181815250508080612e6a9061739d565b915050612dfb565b819250505092915050565b5f612e8784613609565b15612ebb578160018351612e9b9190617280565b81518110612eac57612eab61700d565b5b60200260200101519050612ee1565b612ede835f81518110612ed157612ed061700d565b5b6020026020010151613855565b90505b9392505050565b5f60605f601a601f811115612f0057612eff616dba565b5b84601f811115612f1357612f12616dba565b5b1490505f5f90505b85518160ff161015612f835782612f4e878360ff1681518110612f4157612f4061700d565b5b6020026020010151613a21565b604051602001612f5f9291906173ff565b60405160208183030381529060405292508080612f7b9061739d565b915050612f1b565b50601e601f811115612f9857612f97616dba565b5b84601f811115612fab57612faa616dba565b5b03612ffb57600f935081612fd8865f81518110612fcb57612fca61700d565b5b6020026020010151613a21565b604051602001612fe99291906173ff565b60405160208183030381529060405291505b5f84601f81111561300f5761300e616dba565b5b60f81b9050828160405160200161302792919061746d565b60405160208183030381529060405292505f838051906020012090505f61305b825f1c8a6130558a8e613a83565b876133c7565b90508095505050505050949350505050565b6001815114806130845750613083826002613bae565b5b1561310c577fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f815181106130bf576130be61700d565b5b60200260200101515f5f6040516130da9594939291906174cd565b60405180910390a16131078383835f815181106130fa576130f961700d565b5b6020026020010151613bc9565b6132bd565b60028151036131cf577fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f8151811061314b5761314a61700d565b5b6020026020010151846001815181106131675761316661700d565b5b60200260200101515f604051613181959493929190617525565b60405180910390a16131ca8383835f815181106131a1576131a061700d565b5b6020026020010151846001815181106131bd576131bc61700d565b5b6020026020010151613e30565b6132bc565b7fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f815181106132055761320461700d565b5b6020026020010151846001815181106132215761322061700d565b5b60200260200101518560028151811061323d5761323c61700d565b5b602002602001015160405161325695949392919061757d565b60405180910390a16132bb8383835f815181106132765761327561700d565b5b6020026020010151846001815181106132925761329161700d565b5b6020026020010151856002815181106132ae576132ad61700d565b5b6020026020010151614c5c565b5b5b505050565b5f600760049054906101000a900460030b60030b8260030b121580156132fc575060075f9054906101000a900460030b60030b8260030b13155b9050919050565b5f5f835f015184604001518560200151854660405160200161332995949392919061766e565b60405160208183030381529060405290505f818051906020012090505f613354828760600151614e03565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036133bb576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80935050505092915050565b5f61ffff80167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6133f89190617280565b851690505f8460ff16600861340d8587614e2d565b901b179050808217915050949350505050565b5f600160ff8016901c60ff1660ff801661343a9190617280565b600160ff8016901c60ff1660ff80166134539190617280565b8316149050919050565b5f5f9054906101000a900460ff1615613546576135456040518060400160405280600481526020017fe2949c20000000000000000000000000000000000000000000000000000000008152506134d58560107f2000000000000000000000000000000000000000000000000000000000000000614e6c565b6040518060400160405280600381526020017f207c20000000000000000000000000000000000000000000000000000000000081525061351486614fb3565b61351d8661514f565b60405160200161353195949392919061772c565b60405160208183030381529060405261517c565b5b505050565b5f5f61355683615215565b90506001816001901b03915050919050565b8160015f8581526020019081526020015f2081905550600160025f8581526020019081526020015f205f6101000a81548160ff0219169083151502179055508015613604576136036040518060400160405280600381526020017f736574000000000000000000000000000000000000000000000000000000000081525060405180602001604052805f8152506135fe86614fb3565b6152ec565b5b505050565b5f601b601f81111561361e5761361d616dba565b5b82601f81111561363157613630616dba565b5b14806136615750601a601f81111561364c5761364b616dba565b5b82601f81111561365f5761365e616dba565b5b145b9050919050565b60038151146136b257805160036040517f9a84351c0000000000000000000000000000000000000000000000000000000081526004016136a99291906177cf565b60405180910390fd5b5f6136f4826002815181106136ca576136c961700d565b5b6020026020010151836001815181106136e6576136e561700d565b5b602002602001015118613837565b14613734576040517f52b50ae100000000000000000000000000000000000000000000000000000000815260040161372b90617809565b60405180910390fd5b5f613758825f8151811061374b5761374a61700d565b5b60200260200101516153ca565b90505f5f821860ff16146137a557805f6040517f884a0e9d00000000000000000000000000000000000000000000000000000000815260040161379c929190617836565b60405180910390fd5b5050565b5f600c601f8111156137be576137bd616dba565b5b82601f8111156137d1576137d0616dba565b5b14806138015750601e601f8111156137ec576137eb616dba565b5b82601f8111156137ff576137fe616dba565b5b145b8061383057506002601f81111561381b5761381a616dba565b5b82601f81111561382e5761382d616dba565b5b145b9050919050565b5f8160ff80166008600160ff8016901c60ff16901b17169050919050565b5f60ff801682165f0b9050919050565b5f5f90505b81518160ff1610156138af5761389c828260ff168151811061388f5761388e61700d565b5b6020026020010151611d97565b80806138a79061739d565b91505061386a565b5050565b6138bc836153e6565b613a1c576138c9836154a3565b1561396f575f5f90505b81518160ff161015613969575f613906838360ff16815181106138f9576138f861700d565b5b60200260200101516153ca565b90505f6007821860ff1603613955578360076040517f91b4b37800000000000000000000000000000000000000000000000000000000815260040161394c92919061785d565b60405180910390fd5b5080806139619061739d565b9150506138d3565b50613a1b565b5f5f90505b81518160ff161015613a19575f6139a7838360ff168151811061399a5761399961700d565b5b60200260200101516153ca565b90505f6007821860ff1614806139c157505f5f821860ff16145b15613a055783816040517f91b4b3780000000000000000000000000000000000000000000000000000000081526004016139fc92919061785d565b60405180910390fd5b508080613a119061739d565b915050613974565b505b5b505050565b60605f602067ffffffffffffffff811115613a3f57613a3e616187565b5b6040519080825280601f01601f191660200182016040528015613a715781602001600182028036833780820191505090505b50905082602082015280915050919050565b5f6013601f811115613a9857613a97616dba565b5b83601f811115613aab57613aaa616dba565b5b1480613adb57506014601f811115613ac657613ac5616dba565b5b83601f811115613ad957613ad8616dba565b5b145b80613b0a57506012601f811115613af557613af4616dba565b5b83601f811115613b0857613b07616dba565b5b145b80613b3957506015601f811115613b2457613b23616dba565b5b83601f811115613b3757613b36616dba565b5b145b80613b6857506018601f811115613b5357613b52616dba565b5b83601f811115613b6657613b65616dba565b5b145b80613b9757506019601f811115613b8257613b81616dba565b5b83601f811115613b9557613b94616dba565b5b145b15613ba4575f9050613ba8565b8190505b92915050565b5f613bc183613bbc84611f2c565b615560565b905092915050565b613bd482601b613bae565b15613c4d57613bf283600143613bea9190617280565b405f1c611f0e565b613c486040518060400160405280600a81526020017f4648452e72616e646f6d0000000000000000000000000000000000000000000081525060405180602001604052805f815250613c4386614fb3565b6152ec565b613e2b565b613c58826002613bae565b15613cc457613c6f83613c6a83611e86565b611f0e565b613cbf6040518060400160405280600881526020017f4648452e63617374000000000000000000000000000000000000000000000000815250613cb183614fb3565b613cba86614fb3565b6152ec565b613e2b565b613ccf82600c613bae565b15613d44575f6001613ce083611e86565b149050613cee8482156155b8565b613d3e6040518060400160405280600781526020017f4648452e6e6f7400000000000000000000000000000000000000000000000000815250613d3084614fb3565b613d3987614fb3565b6152ec565b50613e2b565b613d4f82601e613bae565b15613dee57613d7083613d6183611e86565b613d6a84611e86565b02611f0e565b613de96040518060400160405280600a81526020017f4648452e73717561726500000000000000000000000000000000000000000000815250613db283614fb3565b613dbb84614fb3565b604051602001613dcc9291906178b1565b604051602081830303815290604052613de486614fb3565b6152ec565b613e2b565b816040517fd952ce7c000000000000000000000000000000000000000000000000000000008152600401613e2291906168bd565b60405180910390fd5b505050565b613e3b836007613bae565b15613eda57613e5c84613e4d83611e86565b613e5685611e86565b03611f0e565b613ed56040518060400160405280600781526020017f4648452e73756200000000000000000000000000000000000000000000000000815250613e9e84614fb3565b613ea784614fb3565b604051602001613eb8929190617909565b604051602081830303815290604052613ed087614fb3565b6152ec565b614c56565b613ee5836008613bae565b15613f8457613f0684613ef783611e86565b613f0085611e86565b01611f0e565b613f7f6040518060400160405280600781526020017f4648452e61646400000000000000000000000000000000000000000000000000815250613f4884614fb3565b613f5184614fb3565b604051602001613f62929190617961565b604051602081830303815290604052613f7a87614fb3565b6152ec565b614c56565b613f8f836009613bae565b1561402e57613fb084613fa183611e86565b613faa85611e86565b18611f0e565b6140296040518060400160405280600781526020017f4648452e786f7200000000000000000000000000000000000000000000000000815250613ff284614fb3565b613ffb84614fb3565b60405160200161400c9291906179b9565b60405160208183030381529060405261402487614fb3565b6152ec565b614c56565b61403983600a613bae565b156140d85761405a8461404b83611e86565b61405485611e86565b16611f0e565b6140d36040518060400160405280600781526020017f4648452e616e640000000000000000000000000000000000000000000000000081525061409c84614fb3565b6140a584614fb3565b6040516020016140b6929190617a11565b6040516020818303038152906040526140ce87614fb3565b6152ec565b614c56565b6140e383600b613bae565b1561418257614104846140f583611e86565b6140fe85611e86565b17611f0e565b61417d6040518060400160405280600681526020017f4648452e6f72000000000000000000000000000000000000000000000000000081525061414684614fb3565b61414f84614fb3565b604051602001614160929190617a69565b60405160208183030381529060405261417887614fb3565b6152ec565b614c56565b61418d83600d613bae565b15614276575f61419c82611e86565b90505f81036141d4576141cf857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611f0e565b6141f7565b6141f685826141e286611e86565b816141f0576141ef616cc2565b5b04611f0e565b5b6142706040518060400160405280600781526020017f4648452e6469760000000000000000000000000000000000000000000000000081525061423985614fb3565b61424285614fb3565b604051602001614253929190617ac1565b60405160208183030381529060405261426b88614fb3565b6152ec565b50614c56565b61428183600e613bae565b1561432e576142b08461429383611e86565b61429c85611e86565b816142aa576142a9616cc2565b5b06611f0e565b6143296040518060400160405280600781526020017f4648452e72656d000000000000000000000000000000000000000000000000008152506142f284614fb3565b6142fb84614fb3565b60405160200161430c929190617b19565b60405160208183030381529060405261432487614fb3565b6152ec565b614c56565b61433983600f613bae565b156143d85761435a8461434b83611e86565b61435485611e86565b02611f0e565b6143d36040518060400160405280600781526020017f4648452e6d756c0000000000000000000000000000000000000000000000000081525061439c84614fb3565b6143a584614fb3565b6040516020016143b69291906178b1565b6040516020818303038152906040526143ce87614fb3565b6152ec565b614c56565b6143e3836010613bae565b1561448357614405846143f583611e86565b6143fe85611e86565b901b611f0e565b61447e6040518060400160405280600781526020017f4648452e73686c0000000000000000000000000000000000000000000000000081525061444784614fb3565b61445084614fb3565b604051602001614461929190617b71565b60405160208183030381529060405261447987614fb3565b6152ec565b614c56565b61448e836011613bae565b1561452e576144b0846144a083611e86565b6144a985611e86565b901c611f0e565b6145296040518060400160405280600781526020017f4648452e736872000000000000000000000000000000000000000000000000008152506144f284614fb3565b6144fb84614fb3565b60405160200161450c929190617bc9565b60405160208183030381529060405261452487614fb3565b6152ec565b614c56565b614539836012613bae565b156145d95761455b8461454b83611e86565b61455485611e86565b10156155b8565b6145d46040518060400160405280600781526020017f4648452e6774650000000000000000000000000000000000000000000000000081525061459d84614fb3565b6145a684614fb3565b6040516020016145b7929190617c21565b6040516020818303038152906040526145cf87614fb3565b6152ec565b614c56565b6145e4836013613bae565b1561468457614606846145f683611e86565b6145ff85611e86565b11156155b8565b61467f6040518060400160405280600781526020017f4648452e6c74650000000000000000000000000000000000000000000000000081525061464884614fb3565b61465184614fb3565b604051602001614662929190617c79565b60405160208183030381529060405261467a87614fb3565b6152ec565b614c56565b61468f836014613bae565b1561472e576146b0846146a183611e86565b6146aa85611e86565b106155b8565b6147296040518060400160405280600681526020017f4648452e6c7400000000000000000000000000000000000000000000000000008152506146f284614fb3565b6146fb84614fb3565b60405160200161470c929190617cd1565b60405160208183030381529060405261472487614fb3565b6152ec565b614c56565b614739836015613bae565b156147d85761475a8461474b83611e86565b61475485611e86565b116155b8565b6147d36040518060400160405280600681526020017f4648452e6774000000000000000000000000000000000000000000000000000081525061479c84614fb3565b6147a584614fb3565b6040516020016147b6929190617d29565b6040516020818303038152906040526147ce87614fb3565b6152ec565b614c56565b6147e3836016613bae565b156148a3575f6147f282611e86565b6147fb84611e86565b1061480e5761480982611e86565b614818565b61481783611e86565b5b90506148248582611f0e565b61489d6040518060400160405280600781526020017f4648452e6d696e0000000000000000000000000000000000000000000000000081525061486685614fb3565b61486f85614fb3565b604051602001614880929190617dcd565b60405160208183030381529060405261489888614fb3565b6152ec565b50614c56565b6148ae836017613bae565b1561496e575f6148bd82611e86565b6148c684611e86565b116148d9576148d482611e86565b6148e3565b6148e283611e86565b5b90506148ef8582611f0e565b6149686040518060400160405280600781526020017f4648452e6d61780000000000000000000000000000000000000000000000000081525061493185614fb3565b61493a85614fb3565b60405160200161494b929190617e43565b60405160208183030381529060405261496388614fb3565b6152ec565b50614c56565b614979836018613bae565b15614a185761499a8461498b83611e86565b61499485611e86565b146155b8565b614a136040518060400160405280600681526020017f4648452e657100000000000000000000000000000000000000000000000000008152506149dc84614fb3565b6149e584614fb3565b6040516020016149f6929190617eb9565b604051602081830303815290604052614a0e87614fb3565b6152ec565b614c56565b614a23836019613bae565b15614ac357614a4584614a3583611e86565b614a3e85611e86565b14156155b8565b614abe6040518060400160405280600681526020017f4648452e6e650000000000000000000000000000000000000000000000000000815250614a8784614fb3565b614a9084614fb3565b604051602001614aa1929190617f11565b604051602081830303815290604052614ab987614fb3565b6152ec565b614c56565b614ace83601c613bae565b15614b6e57614af084614ae083611e86565b614ae985611e86565b901b611f0e565b614b696040518060400160405280600781526020017f4648452e726f6c00000000000000000000000000000000000000000000000000815250614b3284614fb3565b614b3b84614fb3565b604051602001614b4c929190617b71565b604051602081830303815290604052614b6487614fb3565b6152ec565b614c56565b614b7983601d613bae565b15614c1957614b9b84614b8b83611e86565b614b9485611e86565b901c611f0e565b614c146040518060400160405280600781526020017f4648452e726f7200000000000000000000000000000000000000000000000000815250614bdd84614fb3565b614be684614fb3565b604051602001614bf7929190617bc9565b604051602081830303815290604052614c0f87614fb3565b6152ec565b614c56565b826040517fcef60885000000000000000000000000000000000000000000000000000000008152600401614c4d91906168bd565b60405180910390fd5b50505050565b614c6784601a613bae565b15614cf657614c768584611f0e565b614cf1614c8a614c85876155d6565b611ab6565b604051602001614c9a9190617f69565b604051602081830303815290604052614cba614cb5886155d6565b611ab6565b614cc386615882565b604051602001614cd4929190617fb4565b604051602081830303815290604052614cec88614fb3565b6152ec565b614dfc565b614d01846004613bae565b15614dbf57614d37856001614d1586611e86565b14614d2857614d2383611e86565b614d32565b614d3184611e86565b5b611f0e565b614dba6040518060400160405280600a81526020017f4648452e73656c65637400000000000000000000000000000000000000000000815250614d7985614fb3565b614d8285614fb3565b614d8b85614fb3565b604051602001614d9d93929190618041565b604051602081830303815290604052614db588614fb3565b6152ec565b614dfc565b836040517f5e45fa01000000000000000000000000000000000000000000000000000000008152600401614df391906168bd565b60405180910390fd5b5050505050565b5f5f5f5f614e11868661594c565b925092509250614e2182826159a1565b82935050505092915050565b5f600160ff8016901c60ff168260ff161683614e49575f614e63565b600160ff8016901c60ff1660ff8016614e629190617280565b5b17905092915050565b60605f84905083815110614e835784915050614fac565b5f8467ffffffffffffffff811115614e9e57614e9d616187565b5b6040519080825280601f01601f191660200182016040528015614ed05781602001600182028036833780820191505090505b5090505f5f90505b8251811015614f4d57828181518110614ef457614ef361700d565b5b602001015160f81c60f81b828281518110614f1257614f1161700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050614ed8565b5b85811015614fa55784828281518110614f6a57614f6961700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050614f4e565b8193505050505b9392505050565b60605f614fbf83615882565b90505f8151905060068111614fd857819250505061514a565b5f60025f8681526020019081526020015f205f9054906101000a900460ff1690505f60015f8781526020019081526020015f205490505f61501887615b03565b90505f8161502e5761502983615882565b6150a9565b60018314615071576040518060400160405280600581526020017f66616c73650000000000000000000000000000000000000000000000000000008152506150a8565b6040518060400160405280600481526020017f74727565000000000000000000000000000000000000000000000000000000008152505b5b90505f6150b5896155d6565b6150c1885f60046112ee565b6150d98960048a6150d29190617280565b60046112ee565b87615119576040518060400160405280600581526020017f454d50545900000000000000000000000000000000000000000000000000000081525061511b565b845b60405160200161512e9493929190618101565b6040516020818303038152906040529050809750505050505050505b919050565b60606151758273ffffffffffffffffffffffffffffffffffffffff16601460ff16615b20565b9050919050565b6152128160405160240161519091906168bd565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050615d5e565b50565b5f5f61522083615d78565b90505f60ff168160ff16036152395760089150506152e7565b600260ff168160ff16036152515760089150506152e7565b600360ff168160ff16036152695760109150506152e7565b600460ff168160ff16036152815760209150506152e7565b600560ff168160ff16036152995760409150506152e7565b600660ff168160ff16036152b15760809150506152e7565b600860ff168160ff16036152ca576101009150506152e7565b600760ff168160ff16036152e25760a09150506152e7565b5f9150505b919050565b5f5f9054906101000a900460ff16156153c5576153c46040518060400160405280600481526020017fe2949c20000000000000000000000000000000000000000000000000000000008152506153648560107f2000000000000000000000000000000000000000000000000000000000000000614e6c565b6040518060400160405280600381526020017f207c20000000000000000000000000000000000000000000000000000000000081525085856040516020016153b09594939291906181a0565b60405160208183030381529060405261517c565b5b505050565b5f600880600160ff8016901c60ff16901b8316901c9050919050565b5f6004601f8111156153fb576153fa616dba565b5b82601f81111561540e5761540d616dba565b5b148061543e57506018601f81111561542957615428616dba565b5b82601f81111561543c5761543b616dba565b5b145b8061546d57506019601f81111561545857615457616dba565b5b82601f81111561546b5761546a616dba565b5b145b8061549c57506002601f81111561548757615486616dba565b5b82601f81111561549a57615499616dba565b5b145b9050919050565b5f6009601f8111156154b8576154b7616dba565b5b82601f8111156154cb576154ca616dba565b5b14806154fb5750600a601f8111156154e6576154e5616dba565b5b82601f8111156154f9576154f8616dba565b5b145b8061552a5750600b601f81111561551557615514616dba565b5b82601f81111561552857615527616dba565b5b145b806155595750600c601f81111561554457615543616dba565b5b82601f81111561555757615556616dba565b5b145b9050919050565b5f8160405160200161557291906181f9565b604051602081830303815290604052805190602001208360405160200161559991906181f9565b6040516020818303038152906040528051906020012014905092915050565b6155d282826155c7575f6155ca565b60015b60ff16611f0e565b5050565b60605f6155e283615d78565b90505f60ff168160ff160361562f576040518060400160405280600581526020017f65626f6f6c00000000000000000000000000000000000000000000000000000081525091505061587d565b600260ff168160ff160361567b576040518060400160405280600681526020017f6575696e7438000000000000000000000000000000000000000000000000000081525091505061587d565b600360ff168160ff16036156c7576040518060400160405280600781526020017f6575696e7431360000000000000000000000000000000000000000000000000081525091505061587d565b600460ff168160ff1603615713576040518060400160405280600781526020017f6575696e7433320000000000000000000000000000000000000000000000000081525091505061587d565b600560ff168160ff160361575f576040518060400160405280600781526020017f6575696e7436340000000000000000000000000000000000000000000000000081525091505061587d565b600660ff168160ff16036157ab576040518060400160405280600881526020017f6575696e7431323800000000000000000000000000000000000000000000000081525091505061587d565b600860ff168160ff16036157f7576040518060400160405280600881526020017f6575696e7432353600000000000000000000000000000000000000000000000081525091505061587d565b600760ff168160ff1603615843576040518060400160405280600881526020017f656164647265737300000000000000000000000000000000000000000000000081525091505061587d565b6040518060400160405280600781526020017f756e6b6e6f776e000000000000000000000000000000000000000000000000008152509150505b919050565b60605f600161589084615d94565b0190505f8167ffffffffffffffff8111156158ae576158ad616187565b5b6040519080825280601f01601f1916602001820160405280156158e05781602001600182028036833780820191505090505b5090505f82602083010190505b600115615941578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161593657615935616cc2565b5b0494505f85036158ed575b819350505050919050565b5f5f5f604184510361598c575f5f5f602087015192506040870151915060608701515f1a905061597e88828585615ee5565b95509550955050505061599a565b5f600285515f1b9250925092505b9250925092565b5f60038111156159b4576159b3616dba565b5b8260038111156159c7576159c6616dba565b5b0315615aff57600160038111156159e1576159e0616dba565b5b8260038111156159f4576159f3616dba565b5b03615a2b576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115615a3f57615a3e616dba565b5b826003811115615a5257615a51616dba565b5b03615a9657805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401615a8d919061636e565b60405180910390fd5b600380811115615aa957615aa8616dba565b5b826003811115615abc57615abb616dba565b5b03615afe57806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401615af5919061821e565b60405180910390fd5b5b5050565b5f5f615b0e83615d78565b90505f5f821860ff1614915050919050565b60605f8390505f6002846002615b369190618237565b615b409190616d4c565b67ffffffffffffffff811115615b5957615b58616187565b5b6040519080825280601f01601f191660200182016040528015615b8b5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110615bc257615bc161700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110615c2557615c2461700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002615c639190618237565b615c6d9190616d4c565b90505b6001811115615d0c577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110615caf57615cae61700d565b5b1a60f81b828281518110615cc657615cc561700d565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080615d0590618278565b9050615c70565b505f8214615d535784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401615d4a92919061829f565b60405180910390fd5b809250505092915050565b615d7581615d6d615fcc615feb565b63ffffffff16565b50565b5f600880600160ff8016901c60ff16901b8316901c9050919050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310615df0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381615de657615de5616cc2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310615e2d576d04ee2d6d415b85acef81000000008381615e2357615e22616cc2565b5b0492506020810190505b662386f26fc100008310615e5c57662386f26fc100008381615e5257615e51616cc2565b5b0492506010810190505b6305f5e1008310615e85576305f5e1008381615e7b57615e7a616cc2565b5b0492506008810190505b6127108310615eaa576127108381615ea057615e9f616cc2565b5b0492506004810190505b60648310615ecd5760648381615ec357615ec2616cc2565b5b0492506002810190505b600a8310615edc576001810190505b80915050919050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115615f21575f600385925092509250615fc2565b5f6001888888886040515f8152602001604052604051615f4494939291906182c6565b6020604051602081039080840390855afa158015615f64573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603615fb5575f60015f5f1b93509350935050615fc2565b805f5f5f1b935093509350505b9450945094915050565b5f6a636f6e736f6c652e6c6f6790505f5f835160208501845afa505050565b615ff6819050919050565b615ffe618309565b565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61602381616011565b811461602d575f5ffd5b50565b5f8135905061603e8161601a565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61606d82616044565b9050919050565b61607d81616063565b8114616087575f5ffd5b50565b5f8135905061609881616074565b92915050565b5f5f604083850312156160b4576160b3616009565b5b5f6160c185828601616030565b92505060206160d28582860161608a565b9150509250929050565b5f5f604083850312156160f2576160f1616009565b5b5f6160ff85828601616030565b925050602061611085828601616030565b9150509250929050565b5f60ff82169050919050565b61612f8161611a565b8114616139575f5ffd5b50565b5f8135905061614a81616126565b92915050565b6020811061615c575f5ffd5b50565b5f8135905061616d81616150565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6161bd82616177565b810181811067ffffffffffffffff821117156161dc576161db616187565b5b80604052505050565b5f6161ee616000565b90506161fa82826161b4565b919050565b5f67ffffffffffffffff82111561621957616218616187565b5b602082029050602081019050919050565b5f5ffd5b5f61624061623b846161ff565b6161e5565b905080838252602082019050602084028301858111156162635761626261622a565b5b835b8181101561628c57806162788882616030565b845260208401935050602081019050616265565b5050509392505050565b5f82601f8301126162aa576162a9616173565b5b81356162ba84826020860161622e565b91505092915050565b5f5f5f5f608085870312156162db576162da616009565b5b5f6162e88782880161613c565b94505060206162f98782880161615f565b935050604085013567ffffffffffffffff81111561631a5761631961600d565b5b61632687828801616296565b925050606085013567ffffffffffffffff8111156163475761634661600d565b5b61635387828801616296565b91505092959194509250565b61636881616011565b82525050565b5f6020820190506163815f83018461635f565b92915050565b5f6020828403121561639c5761639b616009565b5b5f6163a984828501616030565b91505092915050565b5f8115159050919050565b6163c6816163b2565b82525050565b5f6020820190506163df5f8301846163bd565b92915050565b6163ee81616063565b82525050565b5f6020820190506164075f8301846163e5565b92915050565b5f8160030b9050919050565b6164228161640d565b811461642c575f5ffd5b50565b5f8135905061643d81616419565b92915050565b5f5f6040838503121561645957616458616009565b5b5f6164668582860161642f565b92505060206164778582860161642f565b9150509250929050565b5f5ffd5b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156164a7576164a6616187565b5b6164b082616177565b9050602081019050919050565b828183375f83830152505050565b5f6164dd6164d88461648d565b6161e5565b9050828152602081018484840111156164f9576164f8616489565b5b6165048482856164bd565b509392505050565b5f82601f8301126165205761651f616173565b5b81356165308482602086016164cb565b91505092915050565b5f6080828403121561654e5761654d616481565b5b61655860806161e5565b90505f61656784828501616030565b5f83015250602061657a8482850161613c565b602083015250604061658e8482850161613c565b604083015250606082013567ffffffffffffffff8111156165b2576165b1616485565b5b6165be8482850161650c565b60608301525092915050565b5f5f604083850312156165e0576165df616009565b5b5f83013567ffffffffffffffff8111156165fd576165fc61600d565b5b61660985828601616539565b925050602061661a8582860161608a565b9150509250929050565b5f6040820190506166375f83018561635f565b61664460208301846163bd565b9392505050565b5f67ffffffffffffffff82111561666557616664616187565b5b61666e82616177565b9050602081019050919050565b5f61668d6166888461664b565b6161e5565b9050828152602081018484840111156166a9576166a8616489565b5b6166b48482856164bd565b509392505050565b5f82601f8301126166d0576166cf616173565b5b81356166e084826020860161667b565b91505092915050565b5f5f5f60608486031215616700576166ff616009565b5b5f61670d86828701616030565b935050602084013567ffffffffffffffff81111561672e5761672d61600d565b5b61673a868287016166bc565b925050604084013567ffffffffffffffff81111561675b5761675a61600d565b5b616767868287016166bc565b9150509250925092565b5f6020828403121561678657616785616009565b5b5f6167938482850161642f565b91505092915050565b6167a5816163b2565b81146167af575f5ffd5b50565b5f813590506167c08161679c565b92915050565b5f602082840312156167db576167da616009565b5b5f6167e8848285016167b2565b91505092915050565b5f5f5f6060848603121561680857616807616009565b5b5f84013567ffffffffffffffff8111156168255761682461600d565b5b616831868287016166bc565b935050602061684286828701616030565b925050604061685386828701616030565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61688f8261685d565b6168998185616867565b93506168a9818560208601616877565b6168b281616177565b840191505092915050565b5f6020820190508181035f8301526168d58184616885565b905092915050565b5f5ffd5b5f5f83601f8401126168f6576168f5616173565b5b8235905067ffffffffffffffff811115616913576169126168dd565b5b60208301915083602082028301111561692f5761692e61622a565b5b9250929050565b5f5f5f5f6060858703121561694e5761694d616009565b5b5f61695b87828801616030565b945050602061696c87828801616030565b935050604085013567ffffffffffffffff81111561698d5761698c61600d565b5b616999878288016168e1565b925092505092959194509250565b5f5f5f606084860312156169be576169bd616009565b5b5f84013567ffffffffffffffff8111156169db576169da61600d565b5b6169e7868287016166bc565b93505060206169f886828701616030565b9250506040616a098682870161608a565b9150509250925092565b5f60208284031215616a2857616a27616009565b5b5f616a358482850161608a565b91505092915050565b5f67ffffffffffffffff82169050919050565b616a5a81616a3e565b8114616a64575f5ffd5b50565b5f81359050616a7581616a51565b92915050565b5f819050919050565b616a8d81616a7b565b8114616a97575f5ffd5b50565b5f81359050616aa881616a84565b92915050565b5f6101008284031215616ac457616ac3616481565b5b616acf6101006161e5565b90505f616ade8482850161608a565b5f830152506020616af184828501616a67565b6020830152506040616b058482850161608a565b6040830152506060616b1984828501616030565b6060830152506080616b2d8482850161608a565b60808301525060a0616b4184828501616a9a565b60a08301525060c082013567ffffffffffffffff811115616b6557616b64616485565b5b616b718482850161650c565b60c08301525060e082013567ffffffffffffffff811115616b9557616b94616485565b5b616ba18482850161650c565b60e08301525092915050565b5f5f60408385031215616bc357616bc2616009565b5b5f83013567ffffffffffffffff811115616be057616bdf61600d565b5b616bec85828601616aae565b9250506020616bfd85828601616030565b9150509250929050565b5f60208284031215616c1c57616c1b616009565b5b5f82013567ffffffffffffffff811115616c3957616c3861600d565b5b616c45848285016166bc565b91505092915050565b5f819050919050565b5f616c71616c6c616c6784616044565b616c4e565b616044565b9050919050565b5f616c8282616c57565b9050919050565b5f616c9382616c78565b9050919050565b616ca381616c89565b82525050565b5f602082019050616cbc5f830184616c9a565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f616cf982616011565b9150616d0483616011565b925082616d1457616d13616cc2565b5b828206905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f616d5682616011565b9150616d6183616011565b9250828201905080821115616d7957616d78616d1f565b5b92915050565b5f616d8982616a3e565b9150616d9483616a3e565b9250828201905067ffffffffffffffff811115616db457616db3616d1f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b5f616e0a616e05616e0084616de7565b616c4e565b616011565b9050919050565b616e1a81616df0565b82525050565b5f6060820190508181035f830152616e388186616885565b9050616e47602083018561635f565b616e546040830184616e11565b949350505050565b5f606082019050616e6f5f83018661635f565b616e7c60208301856163e5565b616e8960408301846163e5565b949350505050565b616e9a8161640d565b82525050565b5f606082019050616eb35f830186616e91565b616ec06020830185616e91565b616ecd6040830184616e91565b949350505050565b5f604082019050616ee85f8301856163e5565b616ef560208301846163e5565b9392505050565b5f604082019050616f0f5f83018561635f565b616f1c60208301846163e5565b9392505050565b5f606082019050616f365f83018661635f565b8181036020830152616f488185616885565b90508181036040830152616f5c8184616885565b9050949350505050565b5f81519050616f748161679c565b92915050565b5f60208284031215616f8f57616f8e616009565b5b5f616f9c84828501616f66565b91505092915050565b7f4f7574206f6620626f756e6473000000000000000000000000000000000000005f82015250565b5f616fd9600d83616867565b9150616fe482616fa5565b602082019050919050565b5f6020820190508181035f83015261700681616fcd565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61706c81616011565b82525050565b5f61707d8383617063565b60208301905092915050565b5f602082019050919050565b5f61709f8261703a565b6170a98185617044565b93506170b483617054565b805f5b838110156170e45781516170cb8882617072565b97506170d683617089565b9250506001810190506170b7565b5085935050505092915050565b5f6040820190508181035f8301526171098185617095565b905061711860208301846163e5565b9392505050565b61712881616063565b82525050565b61713781616a3e565b82525050565b61714681616a7b565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6171708261714c565b61717a8185617156565b935061718a818560208601616877565b61719381616177565b840191505092915050565b5f61010083015f8301516171b45f86018261711f565b5060208301516171c7602086018261712e565b5060408301516171da604086018261711f565b5060608301516171ed6060860182617063565b506080830151617200608086018261711f565b5060a083015161721360a086018261713d565b5060c083015184820360c086015261722b8282617166565b91505060e083015184820360e08601526172458282617166565b9150508091505092915050565b5f6040820190508181035f83015261726a818561719e565b9050617279602083018461635f565b9392505050565b5f61728a82616011565b915061729583616011565b92508282039050818111156172ad576172ac616d1f565b5b92915050565b5f819050919050565b5f6172d66172d16172cc846172b3565b616c4e565b616011565b9050919050565b6172e6816172bc565b82525050565b5f6060820190508181035f8301526173048186616885565b9050617313602083018561635f565b61732060408301846172dd565b949350505050565b5f819050919050565b5f61734b61734661734184617328565b616c4e565b616011565b9050919050565b61735b81617331565b82525050565b5f6060820190508181035f8301526173798186616885565b9050617388602083018561635f565b6173956040830184617352565b949350505050565b5f6173a78261611a565b915060ff82036173ba576173b9616d1f565b5b600182019050919050565b5f81905092915050565b5f6173d98261714c565b6173e381856173c5565b93506173f3818560208601616877565b80840191505092915050565b5f61740a82856173cf565b915061741682846173cf565b91508190509392505050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b61746761746282617422565b61744d565b82525050565b5f61747882856173cf565b91506174848284617456565b6001820191508190509392505050565b5f819050919050565b5f6174b76174b26174ad84617494565b616c4e565b616011565b9050919050565b6174c78161749d565b82525050565b5f60a0820190506174e05f83018861635f565b81810360208301526174f28187616885565b9050617501604083018661635f565b61750e60608301856174be565b61751b60808301846174be565b9695505050505050565b5f60a0820190506175385f83018861635f565b818103602083015261754a8187616885565b9050617559604083018661635f565b617566606083018561635f565b61757360808301846174be565b9695505050505050565b5f60a0820190506175905f83018861635f565b81810360208301526175a28187616885565b90506175b1604083018661635f565b6175be606083018561635f565b6175cb608083018461635f565b9695505050505050565b5f819050919050565b6175ef6175ea82616011565b6175d5565b82525050565b5f8160f81b9050919050565b5f61760b826175f5565b9050919050565b61762361761e8261611a565b617601565b82525050565b5f8160601b9050919050565b5f61763f82617629565b9050919050565b5f61765082617635565b9050919050565b61766861766382616063565b617646565b82525050565b5f61767982886175de565b6020820191506176898287617612565b6001820191506176998286617612565b6001820191506176a98285617657565b6014820191506176b982846175de565b6020820191508190509695505050505050565b5f81905092915050565b5f6176e08261685d565b6176ea81856176cc565b93506176fa818560208601616877565b80840191505092915050565b7f202d3e2000000000000000000000000000000000000000000000000000000000815250565b5f61773782886176d6565b915061774382876176d6565b915061774f82866176d6565b915061775b82856176d6565b915061776682617706565b60048201915061777682846176d6565b91508190509695505050505050565b7f73656c65637400000000000000000000000000000000000000000000000000005f82015250565b5f6177b9600683616867565b91506177c482617785565b602082019050919050565b5f6060820190508181035f8301526177e6816177ad565b90506177f5602083018561635f565b6178026040830184616e11565b9392505050565b5f6020820190508181035f830152617820816177ad565b9050919050565b6178308161611a565b82525050565b5f6040820190506178495f830185617827565b6178566020830184617827565b9392505050565b5f6040820190508181035f8301526178758185616885565b90506178846020830184617827565b9392505050565b7f202a200000000000000000000000000000000000000000000000000000000000815250565b5f6178bc82856176d6565b91506178c78261788b565b6003820191506178d782846176d6565b91508190509392505050565b7f202d200000000000000000000000000000000000000000000000000000000000815250565b5f61791482856176d6565b915061791f826178e3565b60038201915061792f82846176d6565b91508190509392505050565b7f202b200000000000000000000000000000000000000000000000000000000000815250565b5f61796c82856176d6565b91506179778261793b565b60038201915061798782846176d6565b91508190509392505050565b7f205e200000000000000000000000000000000000000000000000000000000000815250565b5f6179c482856176d6565b91506179cf82617993565b6003820191506179df82846176d6565b91508190509392505050565b7f2026200000000000000000000000000000000000000000000000000000000000815250565b5f617a1c82856176d6565b9150617a27826179eb565b600382019150617a3782846176d6565b91508190509392505050565b7f207c200000000000000000000000000000000000000000000000000000000000815250565b5f617a7482856176d6565b9150617a7f82617a43565b600382019150617a8f82846176d6565b91508190509392505050565b7f202f200000000000000000000000000000000000000000000000000000000000815250565b5f617acc82856176d6565b9150617ad782617a9b565b600382019150617ae782846176d6565b91508190509392505050565b7f2025200000000000000000000000000000000000000000000000000000000000815250565b5f617b2482856176d6565b9150617b2f82617af3565b600382019150617b3f82846176d6565b91508190509392505050565b7f203c3c2000000000000000000000000000000000000000000000000000000000815250565b5f617b7c82856176d6565b9150617b8782617b4b565b600482019150617b9782846176d6565b91508190509392505050565b7f203e3e2000000000000000000000000000000000000000000000000000000000815250565b5f617bd482856176d6565b9150617bdf82617ba3565b600482019150617bef82846176d6565b91508190509392505050565b7f203e3d2000000000000000000000000000000000000000000000000000000000815250565b5f617c2c82856176d6565b9150617c3782617bfb565b600482019150617c4782846176d6565b91508190509392505050565b7f203c3d2000000000000000000000000000000000000000000000000000000000815250565b5f617c8482856176d6565b9150617c8f82617c53565b600482019150617c9f82846176d6565b91508190509392505050565b7f203c200000000000000000000000000000000000000000000000000000000000815250565b5f617cdc82856176d6565b9150617ce782617cab565b600382019150617cf782846176d6565b91508190509392505050565b7f203e200000000000000000000000000000000000000000000000000000000000815250565b5f617d3482856176d6565b9150617d3f82617d03565b600382019150617d4f82846176d6565b91508190509392505050565b7f6d696e2800000000000000000000000000000000000000000000000000000000815250565b7f2c20000000000000000000000000000000000000000000000000000000000000815250565b7f2900000000000000000000000000000000000000000000000000000000000000815250565b5f617dd782617d5b565b600482019150617de782856176d6565b9150617df282617d81565b600282019150617e0282846176d6565b9150617e0d82617da7565b6001820191508190509392505050565b7f6d61782800000000000000000000000000000000000000000000000000000000815250565b5f617e4d82617e1d565b600482019150617e5d82856176d6565b9150617e6882617d81565b600282019150617e7882846176d6565b9150617e8382617da7565b6001820191508190509392505050565b7f203d3d2000000000000000000000000000000000000000000000000000000000815250565b5f617ec482856176d6565b9150617ecf82617e93565b600482019150617edf82846176d6565b91508190509392505050565b7f20213d2000000000000000000000000000000000000000000000000000000000815250565b5f617f1c82856176d6565b9150617f2782617eeb565b600482019150617f3782846176d6565b91508190509392505050565b7f4648452e61734500000000000000000000000000000000000000000000000000815250565b5f617f7382617f43565b600782019150617f8382846176d6565b915081905092915050565b7f2800000000000000000000000000000000000000000000000000000000000000815250565b5f617fbf82856176d6565b9150617fca82617f8e565b600182019150617fda82846176d6565b9150617fe582617da7565b6001820191508190509392505050565b7f203f200000000000000000000000000000000000000000000000000000000000815250565b7f203a200000000000000000000000000000000000000000000000000000000000815250565b5f61804c82866176d6565b915061805782617ff5565b60038201915061806782856176d6565b91506180728261801b565b60038201915061808282846176d6565b9150819050949350505050565b7f2e2e000000000000000000000000000000000000000000000000000000000000815250565b7f295b000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b5f61810c82876176d6565b915061811782617f8e565b60018201915061812782866176d6565b91506181328261808f565b60028201915061814282856176d6565b915061814d826180b5565b60028201915061815d82846176d6565b9150618168826180db565b60018201915081905095945050505050565b7f20203d3e20200000000000000000000000000000000000000000000000000000815250565b5f6181ab82886176d6565b91506181b782876176d6565b91506181c382866176d6565b91506181cf82856176d6565b91506181da8261817a565b6006820191506181ea82846176d6565b91508190509695505050505050565b5f61820482846176d6565b915081905092915050565b61821881616a7b565b82525050565b5f6020820190506182315f83018461820f565b92915050565b5f61824182616011565b915061824c83616011565b925082820261825a81616011565b9150828204841483151761827157618270616d1f565b5b5092915050565b5f61828282616011565b91505f820361829457618293616d1f565b5b600182039050919050565b5f6040820190506182b25f83018561635f565b6182bf602083018461635f565b9392505050565b5f6080820190506182d95f83018761820f565b6182e66020830186617827565b6182f3604083018561820f565b618300606083018461820f565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfea2646970667358221220f1a21e362fdc96cf080b052bd034de2e509393b30b09196917450b9a297c45fe64736f6c63430008210033', + '0x608060405234801561000f575f5ffd5b5060043610610246575f3560e01c806365d0509c11610139578063938fb3d9116100b6578063d521ed4b1161007a578063d521ed4b14610717578063de28735914610747578063e68d826f14610765578063f6bc7f3f14610783578063f9120af6146107b357610246565b8063938fb3d914610661578063a307d21d1461067f578063a33b4b0a1461069b578063ae79f04a146106cb578063c4d66de8146106fb57610246565b80638b2b9c23116100fd5780638b2b9c23146105c15780638d9c9c92146105dd5780638db39c8d146105f95780638eef9ae71461061557806392bd6c951461064557610246565b806365d0509c1461050d57806373301651146105295780637e5cf5191461054557806380d55b691461057557806381ba0986146105a557610246565b806327f9c762116101c75780634d7cb0c01161018b5780634d7cb0c014610459578063591363c7146104895780635faa299a146104a55780635fb0bf91146104d5578063642b3f19146104f157610246565b806327f9c762146103a257806334ef1e5a146103d2578063392e53cd146103ee578063458693c91461040c5780634bc982631461043d57610246565b80631d0319311161020e5780631d031931146102fe578063245a7bfc1461032e5780632605ab9f1461034c57806326594a0c14610368578063267c4ae41461038457610246565b8063082898271461024a57806315a486fe1461026657806318683701146102825780631888debd1461029e5780631c76642b146102ce575b5f5ffd5b610264600480360381019061025f9190616912565b6107cf565b005b610280600480360381019061027b9190616950565b610882565b005b61029c600480360381019061029791906169ef565b610890565b005b6102b860048036038101906102b39190616c01565b610968565b6040516102c59190616cac565b60405180910390f35b6102e860048036038101906102e39190616cc5565b610b0c565b6040516102f59190616cac565b60405180910390f35b61031860048036038101906103139190616cc5565b610b21565b6040516103259190616d0a565b60405180910390f35b610336610b3e565b6040516103439190616d32565b60405180910390f35b61036660048036038101906103619190616d4b565b610b64565b005b610382600480360381019061037d9190616dac565b610c38565b005b61038c610d14565b6040516103999190616d0a565b60405180910390f35b6103bc60048036038101906103b79190616f33565b610d1c565b6040516103c99190616cac565b60405180910390f35b6103ec60048036038101906103e79190616cc5565b610f56565b005b6103f6611030565b6040516104039190616d0a565b60405180910390f35b61042660048036038101906104219190616cc5565b611046565b604051610434929190616f8d565b60405180910390f35b61045760048036038101906104529190617052565b6110d4565b005b610473600480360381019061046e91906169ef565b6111a6565b6040516104809190616d0a565b60405180910390f35b6104a3600480360381019061049e91906170da565b611278565b005b6104bf60048036038101906104ba9190616912565b6113aa565b6040516104cc9190616d0a565b60405180910390f35b6104ef60048036038101906104ea91906170da565b611466565b005b61050b6004803603810190610506919061712f565b611598565b005b61052760048036038101906105229190616912565b6115b3565b005b610543600480360381019061053e9190617204565b6116ff565b005b61055f600480360381019061055a91906172b4565b6117e6565b60405161056c9190617380565b60405180910390f35b61058f600480360381019061058a91906173a0565b61191c565b60405161059c9190616cac565b60405180910390f35b6105bf60048036038101906105ba9190617445565b611955565b005b6105db60048036038101906105d691906174b6565b611a63565b005b6105f760048036038101906105f29190616912565b611a73565b005b610613600480360381019061060e9190616d4b565b611b50565b005b61062f600480360381019061062a9190616cc5565b611c24565b60405161063c9190616d0a565b60405180910390f35b61065f600480360381019061065a9190616d4b565b611c2e565b005b610669611d67565b6040516106769190616d32565b60405180910390f35b61069960048036038101906106949190616cc5565b611d8c565b005b6106b560048036038101906106b091906169ef565b611ed4565b6040516106c29190616d0a565b60405180910390f35b6106e560048036038101906106e09190617691565b611f67565b6040516106f29190616d0a565b60405180910390f35b61071560048036038101906107109190616d4b565b61200b565b005b610731600480360381019061072c91906176eb565b6120a9565b60405161073e9190617380565b60405180910390f35b61074f6121be565b60405161075c919061778d565b60405180910390f35b61076d6121e3565b60405161077a9190616d0a565b60405180910390f35b61079d60048036038101906107989190616cc5565b6121f4565b6040516107aa9190616cac565b60405180910390f35b6107cd60048036038101906107c89190616d4b565b612250565b005b6107d88261238a565b600160055f8481526020019081526020015f205f6101000a81548160ff02191690831515021790555061080a82612479565b60045f8481526020019081526020015f20819055505f6001600a4261082f91906177d3565b6108399190617830565b905080426108479190617863565b60065f8581526020019081526020015f205f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b61088c8282612501565b5050565b61089c8484848461251f565b600160055f8681526020019081526020015f205f6101000a81548160ff0219169083151502179055508260045f8681526020019081526020015f20819055504260065f8681526020019081526020015f205f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f023b156100bf14eedc41deb8cef114c1fce662c306697f3bfaf3dbca58130bf7858560405161095a92919061789e565b60405180910390a250505050565b5f601b601f81111561097d5761097c6178c5565b5b84601f8111156109905761098f6178c5565b5b036109c7576040517f98e08ab000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f825184516109d69190617830565b90506003811115610a2b576109ea85612758565b8160036040517f2b0399d5000000000000000000000000000000000000000000000000000000008152600401610a229392919061792b565b60405180910390fd5b610a3584866132ed565b5f610a408585613567565b90505f610a4e8787876136a9565b90505f610a5d8983858b613714565b905060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228233306040518463ffffffff1660e01b8152600401610abd93929190617967565b5f604051808303815f87803b158015610ad4575f5ffd5b505af1158015610ae6573d5f5f3e3d5ffd5b50505050610afd81610af78a612758565b85613899565b80945050505050949350505050565b6001602052805f5260405f205f915090505481565b6002602052805f5260405f205f915054906101000a900460ff1681565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bf557336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401610bec9190616d32565b60405180910390fd5b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc957336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401610cc09190616d32565b60405180910390fd5b81600760046101000a81548163ffffffff021916908360030b63ffffffff1602179055508060075f6101000a81548163ffffffff021916908360030b63ffffffff1602179055505050565b5f6001905090565b5f5f836020015160ff1690505f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610eaa57610d8581613aee565b610de75780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401610dde939291906179ab565b60405180910390fd5b5f610df28585613b2f565b905060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ea8578060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f7ba5ffb5000000000000000000000000000000000000000000000000000000008152600401610e9f9291906179e0565b60405180910390fd5b505b5f610ebe855f01518387604001515f613bf3565b905060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228233306040518463ffffffff1660e01b8152600401610f1e93929190617967565b5f604051808303815f87803b158015610f35575f5ffd5b505af1158015610f47573d5f5f3e3d5ffd5b50505050809250505092915050565b610f5f81613c4c565b61102d5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663846cd43382336040518363ffffffff1660e01b8152600401610fbf929190617a07565b5f604051808303815f87803b158015610fd6575f5ffd5b505af1158015610fe8573d5f5f3e3d5ffd5b5050505061102c6040518060400160405280600f81526020017f4648452e616c6c6f77476c6f62616c00000000000000000000000000000000008152508233611a63565b5b50565b5f600360149054906101000a900460ff16905090565b5f5f60055f8481526020019081526020015f205f9054906101000a900460ff16611075575f5f915091506110cf565b60065f8481526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff164210156110b6575f5f915091506110cf565b60045f8481526020019081526020015f20546001915091505b915091565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461116657336040517fa974a0fe00000000000000000000000000000000000000000000000000000000815260040161115d9190616d32565b60405180910390fd5b7f66d3f531abdf188fde59b6d2b282dc7c725ef2bb1c6c93954054721a13c1a3fa83838360405161119993929190617a2e565b60405180910390a1505050565b5f5f846040516020016111b99190617a91565b60405160208183030381529060405280519060200120905060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166112568286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613c89565b73ffffffffffffffffffffffffffffffffffffffff1614915050949350505050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461130957336040517f7238ea560000000000000000000000000000000000000000000000000000000081526004016113009190616d32565b60405180910390fd5b600760049054906101000a900460030b60030b8160030b12156113845780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf3600000000000000000000000000000000000000000000000000000000815260040161137b939291906179ab565b60405180910390fd5b8060075f6101000a81548163ffffffff021916908360030b63ffffffff16021790555050565b5f6113b483613c4c565b156113c25760019050611460565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a84846040518363ffffffff1660e01b815260040161141e929190617a07565b602060405180830381865afa158015611439573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145d9190617abf565b90505b92915050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114f757336040517f7238ea560000000000000000000000000000000000000000000000000000000081526004016114ee9190616d32565b60405180910390fd5b60075f9054906101000a900460030b60030b8160030b13156115715780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401611568939291906179ab565b60405180910390fd5b80600760046101000a81548163ffffffff021916908360030b63ffffffff16021790555050565b805f5f6101000a81548160ff02191690831515021790555050565b6115bc82613c4c565b6116fb5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379a3a7fb8383336040518463ffffffff1660e01b815260040161161e93929190617967565b5f604051808303815f87803b158015611635575f5ffd5b505af1158015611647573d5f5f3e3d5ffd5b505050506116fa3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146116bc576040518060400160405280600981526020017f4648452e616c6c6f7700000000000000000000000000000000000000000000008152506116f3565b6040518060400160405280600d81526020017f4648452e616c6c6f7754686973000000000000000000000000000000000000008152505b8383611a63565b5b5050565b5f5f90505b868690508110156117dd573073ffffffffffffffffffffffffffffffffffffffff16631868370188888481811061173e5761173d617aea565b5b9050602002013587878581811061175857611757617aea565b5b9050602002013586868681811061177257611771617aea565b5b90506020028101906117849190617b23565b6040518563ffffffff1660e01b81526004016117a39493929190617bc1565b5f604051808303815f87803b1580156117ba575f5ffd5b505af11580156117cc573d5f5f3e3d5ffd5b505050508080600101915050611704565b50505050505050565b60605f849050805183856117fa9190617830565b111561183b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183290617c49565b60405180910390fd5b5f8367ffffffffffffffff81111561185657611855616ac9565b5b6040519080825280601f01601f1916602001820160405280156118885781602001600182028036833780820191505090505b5090505f5f90505b8481101561190f578281876118a59190617830565b815181106118b6576118b5617aea565b5b602001015160f81c60f81b8282815181106118d4576118d3617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050611890565b5080925050509392505050565b5f838383426040516020016119349493929190617c76565b604051602081830303815290604052805190602001205f1c90509392505050565b600760089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146119e757336040517fa974a0fe0000000000000000000000000000000000000000000000000000000081526004016119de9190616d32565b60405180910390fd5b600160055f8681526020019081526020015f205f6101000a81548160ff0219169083151502179055508260045f8681526020019081526020015f20819055504260065f8681526020019081526020015f205f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050505050565b611a6e838383613cb3565b505050565b611a7c82613c4c565b611b4c5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663484de8228383336040518463ffffffff1660e01b8152600401611ade93929190617967565b5f604051808303815f87803b158015611af5575f5ffd5b505af1158015611b07573d5f5f3e3d5ffd5b50505050611b4b6040518060400160405280601281526020017f4648452e616c6c6f775472616e7369656e7400000000000000000000000000008152508383611a63565b5b5050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611be157336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401611bd89190616d32565b60405180910390fd5b8060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60019050919050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cbf57336040517f7238ea56000000000000000000000000000000000000000000000000000000008152600401611cb69190616d32565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d24576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d9581613c4c565b611ed1575f600167ffffffffffffffff811115611db557611db4616ac9565b5b604051908082528060200260200182016040528015611de35781602001602082028036833780820191505090505b50905081815f81518110611dfa57611df9617aea565b5b60200260200101818152505060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c3839ba82336040518363ffffffff1660e01b8152600401611e62929190617d70565b5f604051808303815f87803b158015611e79575f5ffd5b505af1158015611e8b573d5f5f3e3d5ffd5b50505050611ecf6040518060400160405280601681526020017f4648452e616c6c6f77466f7244656372797074696f6e000000000000000000008152508333611a63565b505b50565b5f3073ffffffffffffffffffffffffffffffffffffffff16634d7cb0c0868686866040518563ffffffff1660e01b8152600401611f149493929190617bc1565b602060405180830381865afa925050508015611f4e57506040513d601f19601f82011682018060405250810190611f4b9190617abf565b60015b611f5a575f9050611f5f565b809150505b949350505050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a84846040518363ffffffff1660e01b8152600401611fc4929190617ed1565b602060405180830381865afa158015611fdf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120039190617abf565b905092915050565b8060035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600360146101000a81548160ff0219169083151502179055505f60095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f8290505f8151036120ce5760405180602001604052805f8152509150506121b9565b5f600182516120dd9190617eff565b67ffffffffffffffff8111156120f6576120f5616ac9565b5b6040519080825280601f01601f1916602001820160405280156121285781602001600182028036833780820191505090505b5090505f600190505b82518110156121b25782818151811061214d5761214c617aea565b5b602001015160f81c60f81b826001836121669190617eff565b8151811061217757612176617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050612131565b5080925050505b919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900460ff1681565b5f5f5f61220084611046565b915091508061224657836040517f70cf655400000000000000000000000000000000000000000000000000000000815260040161223d9190616cac565b60405180910390fd5b8192505050919050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122e157336040517f7238ea560000000000000000000000000000000000000000000000000000000081526004016122d89190616d32565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612346576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61239381613c4c565b6124765760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a82336040518363ffffffff1660e01b81526004016123f3929190617a07565b602060405180830381865afa15801561240e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124329190617abf565b6124755780336040517f4d13139e00000000000000000000000000000000000000000000000000000000815260040161246c929190617a07565b60405180910390fd5b5b50565b5f60025f8381526020019081526020015f205f9054906101000a900460ff166124d957816040517f850a796d0000000000000000000000000000000000000000000000000000000081526004016124d09190616cac565b60405180910390fd5b5f6124e383613da1565b90508060015f8581526020019081526020015f205416915050919050565b5f61250b83613da1565b905061251a838284165f613dbe565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff16600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036125a5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6125b08585613e5f565b90505f5f6126018386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613ea7565b50915091505f6003811115612619576126186178c5565b5b81600381111561262c5761262b6178c5565b5b14158061266457505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561269b576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461274f5781600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517f7ba5ffb50000000000000000000000000000000000000000000000000000000081526004016127469291906179e0565b60405180910390fd5b50505050505050565b60606002601f81111561276e5761276d6178c5565b5b82601f811115612781576127806178c5565b5b036127c3576040518060400160405280600481526020017f636173740000000000000000000000000000000000000000000000000000000081525090506132e8565b6003601f8111156127d7576127d66178c5565b5b82601f8111156127ea576127e96178c5565b5b0361282c576040518060400160405280600a81526020017f7365616c4f75747075740000000000000000000000000000000000000000000081525090506132e8565b6004601f8111156128405761283f6178c5565b5b82601f811115612853576128526178c5565b5b03612895576040518060400160405280600681526020017f73656c656374000000000000000000000000000000000000000000000000000081525090506132e8565b6006601f8111156128a9576128a86178c5565b5b82601f8111156128bc576128bb6178c5565b5b036128fe576040518060400160405280600781526020017f646563727970740000000000000000000000000000000000000000000000000081525090506132e8565b6007601f811115612912576129116178c5565b5b82601f811115612925576129246178c5565b5b03612967576040518060400160405280600381526020017f737562000000000000000000000000000000000000000000000000000000000081525090506132e8565b6008601f81111561297b5761297a6178c5565b5b82601f81111561298e5761298d6178c5565b5b036129d0576040518060400160405280600381526020017f616464000000000000000000000000000000000000000000000000000000000081525090506132e8565b6009601f8111156129e4576129e36178c5565b5b82601f8111156129f7576129f66178c5565b5b03612a39576040518060400160405280600381526020017f786f72000000000000000000000000000000000000000000000000000000000081525090506132e8565b600a601f811115612a4d57612a4c6178c5565b5b82601f811115612a6057612a5f6178c5565b5b03612aa2576040518060400160405280600381526020017f616e64000000000000000000000000000000000000000000000000000000000081525090506132e8565b600b601f811115612ab657612ab56178c5565b5b82601f811115612ac957612ac86178c5565b5b03612b0b576040518060400160405280600281526020017f6f7200000000000000000000000000000000000000000000000000000000000081525090506132e8565b600c601f811115612b1f57612b1e6178c5565b5b82601f811115612b3257612b316178c5565b5b03612b74576040518060400160405280600381526020017f6e6f74000000000000000000000000000000000000000000000000000000000081525090506132e8565b600d601f811115612b8857612b876178c5565b5b82601f811115612b9b57612b9a6178c5565b5b03612bdd576040518060400160405280600381526020017f646976000000000000000000000000000000000000000000000000000000000081525090506132e8565b600e601f811115612bf157612bf06178c5565b5b82601f811115612c0457612c036178c5565b5b03612c46576040518060400160405280600381526020017f72656d000000000000000000000000000000000000000000000000000000000081525090506132e8565b600f601f811115612c5a57612c596178c5565b5b82601f811115612c6d57612c6c6178c5565b5b03612caf576040518060400160405280600381526020017f6d756c000000000000000000000000000000000000000000000000000000000081525090506132e8565b6010601f811115612cc357612cc26178c5565b5b82601f811115612cd657612cd56178c5565b5b03612d18576040518060400160405280600381526020017f73686c000000000000000000000000000000000000000000000000000000000081525090506132e8565b6011601f811115612d2c57612d2b6178c5565b5b82601f811115612d3f57612d3e6178c5565b5b03612d81576040518060400160405280600381526020017f736872000000000000000000000000000000000000000000000000000000000081525090506132e8565b6012601f811115612d9557612d946178c5565b5b82601f811115612da857612da76178c5565b5b03612dea576040518060400160405280600381526020017f677465000000000000000000000000000000000000000000000000000000000081525090506132e8565b6013601f811115612dfe57612dfd6178c5565b5b82601f811115612e1157612e106178c5565b5b03612e53576040518060400160405280600381526020017f6c7465000000000000000000000000000000000000000000000000000000000081525090506132e8565b6014601f811115612e6757612e666178c5565b5b82601f811115612e7a57612e796178c5565b5b03612ebc576040518060400160405280600281526020017f6c7400000000000000000000000000000000000000000000000000000000000081525090506132e8565b6015601f811115612ed057612ecf6178c5565b5b82601f811115612ee357612ee26178c5565b5b03612f25576040518060400160405280600281526020017f677400000000000000000000000000000000000000000000000000000000000081525090506132e8565b6016601f811115612f3957612f386178c5565b5b82601f811115612f4c57612f4b6178c5565b5b03612f8e576040518060400160405280600381526020017f6d696e000000000000000000000000000000000000000000000000000000000081525090506132e8565b6017601f811115612fa257612fa16178c5565b5b82601f811115612fb557612fb46178c5565b5b03612ff7576040518060400160405280600381526020017f6d6178000000000000000000000000000000000000000000000000000000000081525090506132e8565b6018601f81111561300b5761300a6178c5565b5b82601f81111561301e5761301d6178c5565b5b03613060576040518060400160405280600281526020017f657100000000000000000000000000000000000000000000000000000000000081525090506132e8565b6019601f811115613074576130736178c5565b5b82601f811115613087576130866178c5565b5b036130c9576040518060400160405280600281526020017f6e6500000000000000000000000000000000000000000000000000000000000081525090506132e8565b601a601f8111156130dd576130dc6178c5565b5b82601f8111156130f0576130ef6178c5565b5b03613132576040518060400160405280600e81526020017f7472697669616c456e637279707400000000000000000000000000000000000081525090506132e8565b601b601f811115613146576131456178c5565b5b82601f811115613159576131586178c5565b5b0361319b576040518060400160405280600681526020017f72616e646f6d000000000000000000000000000000000000000000000000000081525090506132e8565b601c601f8111156131af576131ae6178c5565b5b82601f8111156131c2576131c16178c5565b5b03613204576040518060400160405280600381526020017f726f6c000000000000000000000000000000000000000000000000000000000081525090506132e8565b601d601f811115613218576132176178c5565b5b82601f81111561322b5761322a6178c5565b5b0361326d576040518060400160405280600381526020017f726f72000000000000000000000000000000000000000000000000000000000081525090506132e8565b601e601f811115613281576132806178c5565b5b82601f811115613294576132936178c5565b5b036132d6576040518060400160405280600681526020017f737175617265000000000000000000000000000000000000000000000000000081525090506132e8565b60405180602001604052805f81525090505b919050565b5f6132f782612758565b90505f8351036133515761330a82613efc565b61334b57806040517fb31612aa0000000000000000000000000000000000000000000000000000000081526004016133429190617380565b60405180910390fd5b50613563565b6004601f811115613365576133646178c5565b5b82601f811115613378576133776178c5565b5b0361338b5761338683613f5b565b6134bb565b6133948261409c565b156133ea5760018351146133e55780835160016040517f9a84351c0000000000000000000000000000000000000000000000000000000081526004016133dc93929190617f6b565b60405180910390fd5b6134ba565b60028351146134365780835160026040517f9a84351c00000000000000000000000000000000000000000000000000000000815260040161342d93929190617fe0565b60405180910390fd5b5f6134778460018151811061344e5761344d617aea565b5b6020026020010151855f8151811061346957613468617aea565b5b60200260200101511861412a565b146134b957806040517f52b50ae10000000000000000000000000000000000000000000000000000000081526004016134b09190617380565b60405180910390fd5b5b5b5f6134df845f815181106134d2576134d1617aea565b5b6020026020010151614148565b90506134ea81613aee565b61354c5780600760049054906101000a900460030b60075f9054906101000a900460030b6040517f24cbcf36000000000000000000000000000000000000000000000000000000008152600401613543939291906179ab565b60405180910390fd5b61355584614158565b6135608383866141a6565b50505b5050565b60605f825184516135789190617830565b67ffffffffffffffff81111561359157613590616ac9565b5b6040519080825280602002602001820160405280156135bf5781602001602082028036833780820191505090505b5090505f5f90505b84518160ff16101561362657848160ff16815181106135e9576135e8617aea565b5b6020026020010151828260ff168151811061360757613606617aea565b5b602002602001018181525050808061361e9061801c565b9150506135c7565b5b835185516136359190617830565b8160ff16101561369e578385518260ff166136509190617eff565b8151811061366157613660617aea565b5b6020026020010151828260ff168151811061367f5761367e617aea565b5b60200260200101818152505080806136969061801c565b915050613627565b819250505092915050565b5f6136b384613efc565b156136e75781600183516136c79190617eff565b815181106136d8576136d7617aea565b5b6020026020010151905061370d565b61370a835f815181106136fd576136fc617aea565b5b6020026020010151614148565b90505b9392505050565b5f60605f601a601f81111561372c5761372b6178c5565b5b84601f81111561373f5761373e6178c5565b5b1490505f5f90505b85518160ff1610156137af578261377a878360ff168151811061376d5761376c617aea565b5b6020026020010151614314565b60405160200161378b92919061807e565b604051602081830303815290604052925080806137a79061801c565b915050613747565b50601e601f8111156137c4576137c36178c5565b5b84601f8111156137d7576137d66178c5565b5b0361382757600f935081613804865f815181106137f7576137f6617aea565b5b6020026020010151614314565b60405160200161381592919061807e565b60405160208183030381529060405291505b5f84601f81111561383b5761383a6178c5565b5b60f81b905082816040516020016138539291906180ec565b60405160208183030381529060405292505f838051906020012090505f613887825f1c8a6138818a8e614376565b87613bf3565b90508095505050505050949350505050565b6001815114806138b057506138af8260026144a1565b5b15613938577fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f815181106138eb576138ea617aea565b5b60200260200101515f5f60405161390695949392919061814c565b60405180910390a16139338383835f8151811061392657613925617aea565b5b60200260200101516144bc565b613ae9565b60028151036139fb577fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f8151811061397757613976617aea565b5b60200260200101518460018151811061399357613992617aea565b5b60200260200101515f6040516139ad9594939291906181a4565b60405180910390a16139f68383835f815181106139cd576139cc617aea565b5b6020026020010151846001815181106139e9576139e8617aea565b5b6020026020010151614723565b613ae8565b7fe9de54a3e7ddf0c48cc6e1134185300d5a71acbf2d8c21fcdefa9d9dd9e20ac18383835f81518110613a3157613a30617aea565b5b602002602001015184600181518110613a4d57613a4c617aea565b5b602002602001015185600281518110613a6957613a68617aea565b5b6020026020010151604051613a829594939291906181fc565b60405180910390a1613ae78383835f81518110613aa257613aa1617aea565b5b602002602001015184600181518110613abe57613abd617aea565b5b602002602001015185600281518110613ada57613ad9617aea565b5b602002602001015161554f565b5b5b505050565b5f600760049054906101000a900460030b60030b8260030b12158015613b28575060075f9054906101000a900460030b60030b8260030b13155b9050919050565b5f5f835f0151846040015185602001518546604051602001613b559594939291906182cd565b60405160208183030381529060405290505f818051906020012090505f613b80828760600151613c89565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613be7576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80935050505092915050565b5f61ffff80167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613c249190617eff565b851690505f8460ff166008613c3985876156f6565b901b179050808217915050949350505050565b5f600160ff8016901c60ff1660ff8016613c669190617eff565b600160ff8016901c60ff1660ff8016613c7f9190617eff565b8316149050919050565b5f5f5f5f613c978686613ea7565b925092509250613ca78282615735565b82935050505092915050565b5f5f9054906101000a900460ff1615613d9c57613d9b6040518060400160405280600481526020017fe2949c2000000000000000000000000000000000000000000000000000000000815250613d2b8560107f2000000000000000000000000000000000000000000000000000000000000000615897565b6040518060400160405280600381526020017f207c200000000000000000000000000000000000000000000000000000000000815250613d6a866159de565b613d7386615b7a565b604051602001613d8795949392919061838b565b604051602081830303815290604052615ba7565b5b505050565b5f5f613dac83615c40565b90506001816001901b03915050919050565b8160015f8581526020019081526020015f2081905550600160025f8581526020019081526020015f205f6101000a81548160ff0219169083151502179055508015613e5a57613e596040518060400160405280600381526020017f736574000000000000000000000000000000000000000000000000000000000081525060405180602001604052805f815250613e54866159de565b615d17565b5b505050565b5f5f613e6a84615df5565b9050828160ff1646865f1b604051602001613e88949392919061847b565b6040516020818303038152906040528051906020012091505092915050565b5f5f5f6041845103613ee7575f5f5f602087015192506040870151915060608701515f1a9050613ed988828585615e11565b955095509550505050613ef5565b5f600285515f1b9250925092505b9250925092565b5f601b601f811115613f1157613f106178c5565b5b82601f811115613f2457613f236178c5565b5b1480613f545750601a601f811115613f3f57613f3e6178c5565b5b82601f811115613f5257613f516178c5565b5b145b9050919050565b6003815114613fa557805160036040517f9a84351c000000000000000000000000000000000000000000000000000000008152600401613f9c929190618512565b60405180910390fd5b5f613fe782600281518110613fbd57613fbc617aea565b5b602002602001015183600181518110613fd957613fd8617aea565b5b60200260200101511861412a565b14614027576040517f52b50ae100000000000000000000000000000000000000000000000000000000815260040161401e9061854c565b60405180910390fd5b5f61404b825f8151811061403e5761403d617aea565b5b6020026020010151615df5565b90505f5f821860ff161461409857805f6040517f884a0e9d00000000000000000000000000000000000000000000000000000000815260040161408f92919061856a565b60405180910390fd5b5050565b5f600c601f8111156140b1576140b06178c5565b5b82601f8111156140c4576140c36178c5565b5b14806140f45750601e601f8111156140df576140de6178c5565b5b82601f8111156140f2576140f16178c5565b5b145b8061412357506002601f81111561410e5761410d6178c5565b5b82601f811115614121576141206178c5565b5b145b9050919050565b5f8160ff80166008600160ff8016901c60ff16901b17169050919050565b5f60ff801682165f0b9050919050565b5f5f90505b81518160ff1610156141a25761418f828260ff168151811061418257614181617aea565b5b602002602001015161238a565b808061419a9061801c565b91505061415d565b5050565b6141af83615ef8565b61430f576141bc83615fb5565b15614262575f5f90505b81518160ff16101561425c575f6141f9838360ff16815181106141ec576141eb617aea565b5b6020026020010151615df5565b90505f6007821860ff1603614248578360076040517f91b4b37800000000000000000000000000000000000000000000000000000000815260040161423f929190618591565b60405180910390fd5b5080806142549061801c565b9150506141c6565b5061430e565b5f5f90505b81518160ff16101561430c575f61429a838360ff168151811061428d5761428c617aea565b5b6020026020010151615df5565b90505f6007821860ff1614806142b457505f5f821860ff16145b156142f85783816040517f91b4b3780000000000000000000000000000000000000000000000000000000081526004016142ef929190618591565b60405180910390fd5b5080806143049061801c565b915050614267565b505b5b505050565b60605f602067ffffffffffffffff81111561433257614331616ac9565b5b6040519080825280601f01601f1916602001820160405280156143645781602001600182028036833780820191505090505b50905082602082015280915050919050565b5f6013601f81111561438b5761438a6178c5565b5b83601f81111561439e5761439d6178c5565b5b14806143ce57506014601f8111156143b9576143b86178c5565b5b83601f8111156143cc576143cb6178c5565b5b145b806143fd57506012601f8111156143e8576143e76178c5565b5b83601f8111156143fb576143fa6178c5565b5b145b8061442c57506015601f811115614417576144166178c5565b5b83601f81111561442a576144296178c5565b5b145b8061445b57506018601f811115614446576144456178c5565b5b83601f811115614459576144586178c5565b5b145b8061448a57506019601f811115614475576144746178c5565b5b83601f811115614488576144876178c5565b5b145b15614497575f905061449b565b8190505b92915050565b5f6144b4836144af84612758565b616072565b905092915050565b6144c782601b6144a1565b15614540576144e5836001436144dd9190617eff565b405f1c612501565b61453b6040518060400160405280600a81526020017f4648452e72616e646f6d0000000000000000000000000000000000000000000081525060405180602001604052805f815250614536866159de565b615d17565b61471e565b61454b8260026144a1565b156145b7576145628361455d83612479565b612501565b6145b26040518060400160405280600881526020017f4648452e636173740000000000000000000000000000000000000000000000008152506145a4836159de565b6145ad866159de565b615d17565b61471e565b6145c282600c6144a1565b15614637575f60016145d383612479565b1490506145e18482156160ca565b6146316040518060400160405280600781526020017f4648452e6e6f7400000000000000000000000000000000000000000000000000815250614623846159de565b61462c876159de565b615d17565b5061471e565b61464282601e6144a1565b156146e1576146638361465483612479565b61465d84612479565b02612501565b6146dc6040518060400160405280600a81526020017f4648452e737175617265000000000000000000000000000000000000000000008152506146a5836159de565b6146ae846159de565b6040516020016146bf9291906185e5565b6040516020818303038152906040526146d7866159de565b615d17565b61471e565b816040517fd952ce7c0000000000000000000000000000000000000000000000000000000081526004016147159190617380565b60405180910390fd5b505050565b61472e8360076144a1565b156147cd5761474f8461474083612479565b61474985612479565b03612501565b6147c86040518060400160405280600781526020017f4648452e73756200000000000000000000000000000000000000000000000000815250614791846159de565b61479a846159de565b6040516020016147ab92919061863d565b6040516020818303038152906040526147c3876159de565b615d17565b615549565b6147d88360086144a1565b15614877576147f9846147ea83612479565b6147f385612479565b01612501565b6148726040518060400160405280600781526020017f4648452e6164640000000000000000000000000000000000000000000000000081525061483b846159de565b614844846159de565b604051602001614855929190618695565b60405160208183030381529060405261486d876159de565b615d17565b615549565b6148828360096144a1565b15614921576148a38461489483612479565b61489d85612479565b18612501565b61491c6040518060400160405280600781526020017f4648452e786f72000000000000000000000000000000000000000000000000008152506148e5846159de565b6148ee846159de565b6040516020016148ff9291906186ed565b604051602081830303815290604052614917876159de565b615d17565b615549565b61492c83600a6144a1565b156149cb5761494d8461493e83612479565b61494785612479565b16612501565b6149c66040518060400160405280600781526020017f4648452e616e640000000000000000000000000000000000000000000000000081525061498f846159de565b614998846159de565b6040516020016149a9929190618745565b6040516020818303038152906040526149c1876159de565b615d17565b615549565b6149d683600b6144a1565b15614a75576149f7846149e883612479565b6149f185612479565b17612501565b614a706040518060400160405280600681526020017f4648452e6f720000000000000000000000000000000000000000000000000000815250614a39846159de565b614a42846159de565b604051602001614a5392919061879d565b604051602081830303815290604052614a6b876159de565b615d17565b615549565b614a8083600d6144a1565b15614b69575f614a8f82612479565b90505f8103614ac757614ac2857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612501565b614aea565b614ae98582614ad586612479565b81614ae357614ae26177a6565b5b04612501565b5b614b636040518060400160405280600781526020017f4648452e64697600000000000000000000000000000000000000000000000000815250614b2c856159de565b614b35856159de565b604051602001614b469291906187f5565b604051602081830303815290604052614b5e886159de565b615d17565b50615549565b614b7483600e6144a1565b15614c2157614ba384614b8683612479565b614b8f85612479565b81614b9d57614b9c6177a6565b5b06612501565b614c1c6040518060400160405280600781526020017f4648452e72656d00000000000000000000000000000000000000000000000000815250614be5846159de565b614bee846159de565b604051602001614bff92919061884d565b604051602081830303815290604052614c17876159de565b615d17565b615549565b614c2c83600f6144a1565b15614ccb57614c4d84614c3e83612479565b614c4785612479565b02612501565b614cc66040518060400160405280600781526020017f4648452e6d756c00000000000000000000000000000000000000000000000000815250614c8f846159de565b614c98846159de565b604051602001614ca99291906185e5565b604051602081830303815290604052614cc1876159de565b615d17565b615549565b614cd68360106144a1565b15614d7657614cf884614ce883612479565b614cf185612479565b901b612501565b614d716040518060400160405280600781526020017f4648452e73686c00000000000000000000000000000000000000000000000000815250614d3a846159de565b614d43846159de565b604051602001614d549291906188a5565b604051602081830303815290604052614d6c876159de565b615d17565b615549565b614d818360116144a1565b15614e2157614da384614d9383612479565b614d9c85612479565b901c612501565b614e1c6040518060400160405280600781526020017f4648452e73687200000000000000000000000000000000000000000000000000815250614de5846159de565b614dee846159de565b604051602001614dff9291906188fd565b604051602081830303815290604052614e17876159de565b615d17565b615549565b614e2c8360126144a1565b15614ecc57614e4e84614e3e83612479565b614e4785612479565b10156160ca565b614ec76040518060400160405280600781526020017f4648452e67746500000000000000000000000000000000000000000000000000815250614e90846159de565b614e99846159de565b604051602001614eaa929190618955565b604051602081830303815290604052614ec2876159de565b615d17565b615549565b614ed78360136144a1565b15614f7757614ef984614ee983612479565b614ef285612479565b11156160ca565b614f726040518060400160405280600781526020017f4648452e6c746500000000000000000000000000000000000000000000000000815250614f3b846159de565b614f44846159de565b604051602001614f559291906189ad565b604051602081830303815290604052614f6d876159de565b615d17565b615549565b614f828360146144a1565b1561502157614fa384614f9483612479565b614f9d85612479565b106160ca565b61501c6040518060400160405280600681526020017f4648452e6c740000000000000000000000000000000000000000000000000000815250614fe5846159de565b614fee846159de565b604051602001614fff929190618a05565b604051602081830303815290604052615017876159de565b615d17565b615549565b61502c8360156144a1565b156150cb5761504d8461503e83612479565b61504785612479565b116160ca565b6150c66040518060400160405280600681526020017f4648452e6774000000000000000000000000000000000000000000000000000081525061508f846159de565b615098846159de565b6040516020016150a9929190618a5d565b6040516020818303038152906040526150c1876159de565b615d17565b615549565b6150d68360166144a1565b15615196575f6150e582612479565b6150ee84612479565b10615101576150fc82612479565b61510b565b61510a83612479565b5b90506151178582612501565b6151906040518060400160405280600781526020017f4648452e6d696e00000000000000000000000000000000000000000000000000815250615159856159de565b615162856159de565b604051602001615173929190618b01565b60405160208183030381529060405261518b886159de565b615d17565b50615549565b6151a18360176144a1565b15615261575f6151b082612479565b6151b984612479565b116151cc576151c782612479565b6151d6565b6151d583612479565b5b90506151e28582612501565b61525b6040518060400160405280600781526020017f4648452e6d617800000000000000000000000000000000000000000000000000815250615224856159de565b61522d856159de565b60405160200161523e929190618b77565b604051602081830303815290604052615256886159de565b615d17565b50615549565b61526c8360186144a1565b1561530b5761528d8461527e83612479565b61528785612479565b146160ca565b6153066040518060400160405280600681526020017f4648452e657100000000000000000000000000000000000000000000000000008152506152cf846159de565b6152d8846159de565b6040516020016152e9929190618bed565b604051602081830303815290604052615301876159de565b615d17565b615549565b6153168360196144a1565b156153b6576153388461532883612479565b61533185612479565b14156160ca565b6153b16040518060400160405280600681526020017f4648452e6e65000000000000000000000000000000000000000000000000000081525061537a846159de565b615383846159de565b604051602001615394929190618c45565b6040516020818303038152906040526153ac876159de565b615d17565b615549565b6153c183601c6144a1565b15615461576153e3846153d383612479565b6153dc85612479565b901b612501565b61545c6040518060400160405280600781526020017f4648452e726f6c00000000000000000000000000000000000000000000000000815250615425846159de565b61542e846159de565b60405160200161543f9291906188a5565b604051602081830303815290604052615457876159de565b615d17565b615549565b61546c83601d6144a1565b1561550c5761548e8461547e83612479565b61548785612479565b901c612501565b6155076040518060400160405280600781526020017f4648452e726f72000000000000000000000000000000000000000000000000008152506154d0846159de565b6154d9846159de565b6040516020016154ea9291906188fd565b604051602081830303815290604052615502876159de565b615d17565b615549565b826040517fcef608850000000000000000000000000000000000000000000000000000000081526004016155409190617380565b60405180910390fd5b50505050565b61555a84601a6144a1565b156155e9576155698584612501565b6155e461557d615578876160e8565b6120a9565b60405160200161558d9190618c9d565b6040516020818303038152906040526155ad6155a8886160e8565b6120a9565b6155b686616394565b6040516020016155c7929190618ce8565b6040516020818303038152906040526155df886159de565b615d17565b6156ef565b6155f48460046144a1565b156156b25761562a85600161560886612479565b1461561b5761561683612479565b615625565b61562484612479565b5b612501565b6156ad6040518060400160405280600a81526020017f4648452e73656c6563740000000000000000000000000000000000000000000081525061566c856159de565b615675856159de565b61567e856159de565b60405160200161569093929190618d75565b6040516020818303038152906040526156a8886159de565b615d17565b6156ef565b836040517f5e45fa010000000000000000000000000000000000000000000000000000000081526004016156e69190617380565b60405180910390fd5b5050505050565b5f600160ff8016901c60ff168260ff161683615712575f61572c565b600160ff8016901c60ff1660ff801661572b9190617eff565b5b17905092915050565b5f6003811115615748576157476178c5565b5b82600381111561575b5761575a6178c5565b5b03156158935760016003811115615775576157746178c5565b5b826003811115615788576157876178c5565b5b036157bf576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600260038111156157d3576157d26178c5565b5b8260038111156157e6576157e56178c5565b5b0361582a57805f1c6040517ffce698f70000000000000000000000000000000000000000000000000000000081526004016158219190616cac565b60405180910390fd5b60038081111561583d5761583c6178c5565b5b8260038111156158505761584f6178c5565b5b0361589257806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016158899190618dd2565b60405180910390fd5b5b5050565b60605f849050838151106158ae57849150506159d7565b5f8467ffffffffffffffff8111156158c9576158c8616ac9565b5b6040519080825280601f01601f1916602001820160405280156158fb5781602001600182028036833780820191505090505b5090505f5f90505b82518110156159785782818151811061591f5761591e617aea565b5b602001015160f81c60f81b82828151811061593d5761593c617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050615903565b5b858110156159d0578482828151811061599557615994617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508080600101915050615979565b8193505050505b9392505050565b60605f6159ea83616394565b90505f8151905060068111615a03578192505050615b75565b5f60025f8681526020019081526020015f205f9054906101000a900460ff1690505f60015f8781526020019081526020015f205490505f615a438761645e565b90505f81615a5957615a5483616394565b615ad4565b60018314615a9c576040518060400160405280600581526020017f66616c7365000000000000000000000000000000000000000000000000000000815250615ad3565b6040518060400160405280600481526020017f74727565000000000000000000000000000000000000000000000000000000008152505b5b90505f615ae0896160e8565b615aec885f60046117e6565b615b048960048a615afd9190617eff565b60046117e6565b87615b44576040518060400160405280600581526020017f454d505459000000000000000000000000000000000000000000000000000000815250615b46565b845b604051602001615b599493929190618e5d565b6040516020818303038152906040529050809750505050505050505b919050565b6060615ba08273ffffffffffffffffffffffffffffffffffffffff16601460ff1661647b565b9050919050565b615c3d81604051602401615bbb9190617380565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506166b9565b50565b5f5f615c4b836166d3565b90505f60ff168160ff1603615c64576008915050615d12565b600260ff168160ff1603615c7c576008915050615d12565b600360ff168160ff1603615c94576010915050615d12565b600460ff168160ff1603615cac576020915050615d12565b600560ff168160ff1603615cc4576040915050615d12565b600660ff168160ff1603615cdc576080915050615d12565b600860ff168160ff1603615cf557610100915050615d12565b600760ff168160ff1603615d0d5760a0915050615d12565b5f9150505b919050565b5f5f9054906101000a900460ff1615615df057615def6040518060400160405280600481526020017fe2949c2000000000000000000000000000000000000000000000000000000000815250615d8f8560107f2000000000000000000000000000000000000000000000000000000000000000615897565b6040518060400160405280600381526020017f207c2000000000000000000000000000000000000000000000000000000000008152508585604051602001615ddb959493929190618efc565b604051602081830303815290604052615ba7565b5b505050565b5f600880600160ff8016901c60ff16901b8316901c9050919050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115615e4d575f600385925092509250615eee565b5f6001888888886040515f8152602001604052604051615e709493929190618f55565b6020604051602081039080840390855afa158015615e90573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603615ee1575f60015f5f1b93509350935050615eee565b805f5f5f1b935093509350505b9450945094915050565b5f6004601f811115615f0d57615f0c6178c5565b5b82601f811115615f2057615f1f6178c5565b5b1480615f5057506018601f811115615f3b57615f3a6178c5565b5b82601f811115615f4e57615f4d6178c5565b5b145b80615f7f57506019601f811115615f6a57615f696178c5565b5b82601f811115615f7d57615f7c6178c5565b5b145b80615fae57506002601f811115615f9957615f986178c5565b5b82601f811115615fac57615fab6178c5565b5b145b9050919050565b5f6009601f811115615fca57615fc96178c5565b5b82601f811115615fdd57615fdc6178c5565b5b148061600d5750600a601f811115615ff857615ff76178c5565b5b82601f81111561600b5761600a6178c5565b5b145b8061603c5750600b601f811115616027576160266178c5565b5b82601f81111561603a576160396178c5565b5b145b8061606b5750600c601f811115616056576160556178c5565b5b82601f811115616069576160686178c5565b5b145b9050919050565b5f816040516020016160849190618f98565b60405160208183030381529060405280519060200120836040516020016160ab9190618f98565b6040516020818303038152906040528051906020012014905092915050565b6160e482826160d9575f6160dc565b60015b60ff16612501565b5050565b60605f6160f4836166d3565b90505f60ff168160ff1603616141576040518060400160405280600581526020017f65626f6f6c00000000000000000000000000000000000000000000000000000081525091505061638f565b600260ff168160ff160361618d576040518060400160405280600681526020017f6575696e7438000000000000000000000000000000000000000000000000000081525091505061638f565b600360ff168160ff16036161d9576040518060400160405280600781526020017f6575696e7431360000000000000000000000000000000000000000000000000081525091505061638f565b600460ff168160ff1603616225576040518060400160405280600781526020017f6575696e7433320000000000000000000000000000000000000000000000000081525091505061638f565b600560ff168160ff1603616271576040518060400160405280600781526020017f6575696e7436340000000000000000000000000000000000000000000000000081525091505061638f565b600660ff168160ff16036162bd576040518060400160405280600881526020017f6575696e7431323800000000000000000000000000000000000000000000000081525091505061638f565b600860ff168160ff1603616309576040518060400160405280600881526020017f6575696e7432353600000000000000000000000000000000000000000000000081525091505061638f565b600760ff168160ff1603616355576040518060400160405280600881526020017f656164647265737300000000000000000000000000000000000000000000000081525091505061638f565b6040518060400160405280600781526020017f756e6b6e6f776e000000000000000000000000000000000000000000000000008152509150505b919050565b60605f60016163a2846166ef565b0190505f8167ffffffffffffffff8111156163c0576163bf616ac9565b5b6040519080825280601f01601f1916602001820160405280156163f25781602001600182028036833780820191505090505b5090505f82602083010190505b600115616453578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581616448576164476177a6565b5b0494505f85036163ff575b819350505050919050565b5f5f616469836166d3565b90505f5f821860ff1614915050919050565b60605f8390505f60028460026164919190618fae565b61649b9190617830565b67ffffffffffffffff8111156164b4576164b3616ac9565b5b6040519080825280601f01601f1916602001820160405280156164e65781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061651d5761651c617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106165805761657f617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f60018560026165be9190618fae565b6165c89190617830565b90505b6001811115616667577f3031323334353637383961626364656600000000000000000000000000000000600f84166010811061660a57616609617aea565b5b1a60f81b82828151811061662157616620617aea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c92508061666090618fef565b90506165cb565b505f82146166ae5784846040517fe22e27eb0000000000000000000000000000000000000000000000000000000081526004016166a592919061789e565b60405180910390fd5b809250505092915050565b6166d0816166c861684061685f565b63ffffffff16565b50565b5f600880600160ff8016901c60ff16901b8316901c9050919050565b5f5f5f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061674b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381616741576167406177a6565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310616788576d04ee2d6d415b85acef8100000000838161677e5761677d6177a6565b5b0492506020810190505b662386f26fc1000083106167b757662386f26fc1000083816167ad576167ac6177a6565b5b0492506010810190505b6305f5e10083106167e0576305f5e10083816167d6576167d56177a6565b5b0492506008810190505b61271083106168055761271083816167fb576167fa6177a6565b5b0492506004810190505b60648310616828576064838161681e5761681d6177a6565b5b0492506002810190505b600a8310616837576001810190505b80915050919050565b5f6a636f6e736f6c652e6c6f6790505f5f835160208501845afa505050565b61686a819050919050565b616872619016565b565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61689781616885565b81146168a1575f5ffd5b50565b5f813590506168b28161688e565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6168e1826168b8565b9050919050565b6168f1816168d7565b81146168fb575f5ffd5b50565b5f8135905061690c816168e8565b92915050565b5f5f604083850312156169285761692761687d565b5b5f616935858286016168a4565b9250506020616946858286016168fe565b9150509250929050565b5f5f604083850312156169665761696561687d565b5b5f616973858286016168a4565b9250506020616984858286016168a4565b9150509250929050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126169af576169ae61698e565b5b8235905067ffffffffffffffff8111156169cc576169cb616992565b5b6020830191508360018202830111156169e8576169e7616996565b5b9250929050565b5f5f5f5f60608587031215616a0757616a0661687d565b5b5f616a14878288016168a4565b9450506020616a25878288016168a4565b935050604085013567ffffffffffffffff811115616a4657616a45616881565b5b616a528782880161699a565b925092505092959194509250565b5f60ff82169050919050565b616a7581616a60565b8114616a7f575f5ffd5b50565b5f81359050616a9081616a6c565b92915050565b60208110616aa2575f5ffd5b50565b5f81359050616ab381616a96565b92915050565b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b616aff82616ab9565b810181811067ffffffffffffffff82111715616b1e57616b1d616ac9565b5b80604052505050565b5f616b30616874565b9050616b3c8282616af6565b919050565b5f67ffffffffffffffff821115616b5b57616b5a616ac9565b5b602082029050602081019050919050565b5f616b7e616b7984616b41565b616b27565b90508083825260208201905060208402830185811115616ba157616ba0616996565b5b835b81811015616bca5780616bb688826168a4565b845260208401935050602081019050616ba3565b5050509392505050565b5f82601f830112616be857616be761698e565b5b8135616bf8848260208601616b6c565b91505092915050565b5f5f5f5f60808587031215616c1957616c1861687d565b5b5f616c2687828801616a82565b9450506020616c3787828801616aa5565b935050604085013567ffffffffffffffff811115616c5857616c57616881565b5b616c6487828801616bd4565b925050606085013567ffffffffffffffff811115616c8557616c84616881565b5b616c9187828801616bd4565b91505092959194509250565b616ca681616885565b82525050565b5f602082019050616cbf5f830184616c9d565b92915050565b5f60208284031215616cda57616cd961687d565b5b5f616ce7848285016168a4565b91505092915050565b5f8115159050919050565b616d0481616cf0565b82525050565b5f602082019050616d1d5f830184616cfb565b92915050565b616d2c816168d7565b82525050565b5f602082019050616d455f830184616d23565b92915050565b5f60208284031215616d6057616d5f61687d565b5b5f616d6d848285016168fe565b91505092915050565b5f8160030b9050919050565b616d8b81616d76565b8114616d95575f5ffd5b50565b5f81359050616da681616d82565b92915050565b5f5f60408385031215616dc257616dc161687d565b5b5f616dcf85828601616d98565b9250506020616de085828601616d98565b9150509250929050565b5f5ffd5b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115616e1057616e0f616ac9565b5b616e1982616ab9565b9050602081019050919050565b828183375f83830152505050565b5f616e46616e4184616df6565b616b27565b905082815260208101848484011115616e6257616e61616df2565b5b616e6d848285616e26565b509392505050565b5f82601f830112616e8957616e8861698e565b5b8135616e99848260208601616e34565b91505092915050565b5f60808284031215616eb757616eb6616dea565b5b616ec16080616b27565b90505f616ed0848285016168a4565b5f830152506020616ee384828501616a82565b6020830152506040616ef784828501616a82565b604083015250606082013567ffffffffffffffff811115616f1b57616f1a616dee565b5b616f2784828501616e75565b60608301525092915050565b5f5f60408385031215616f4957616f4861687d565b5b5f83013567ffffffffffffffff811115616f6657616f65616881565b5b616f7285828601616ea2565b9250506020616f83858286016168fe565b9150509250929050565b5f604082019050616fa05f830185616c9d565b616fad6020830184616cfb565b9392505050565b5f67ffffffffffffffff821115616fce57616fcd616ac9565b5b616fd782616ab9565b9050602081019050919050565b5f616ff6616ff184616fb4565b616b27565b90508281526020810184848401111561701257617011616df2565b5b61701d848285616e26565b509392505050565b5f82601f8301126170395761703861698e565b5b8135617049848260208601616fe4565b91505092915050565b5f5f5f606084860312156170695761706861687d565b5b5f617076868287016168a4565b935050602084013567ffffffffffffffff81111561709757617096616881565b5b6170a386828701617025565b925050604084013567ffffffffffffffff8111156170c4576170c3616881565b5b6170d086828701617025565b9150509250925092565b5f602082840312156170ef576170ee61687d565b5b5f6170fc84828501616d98565b91505092915050565b61710e81616cf0565b8114617118575f5ffd5b50565b5f8135905061712981617105565b92915050565b5f602082840312156171445761714361687d565b5b5f6171518482850161711b565b91505092915050565b5f5f83601f84011261716f5761716e61698e565b5b8235905067ffffffffffffffff81111561718c5761718b616992565b5b6020830191508360208202830111156171a8576171a7616996565b5b9250929050565b5f5f83601f8401126171c4576171c361698e565b5b8235905067ffffffffffffffff8111156171e1576171e0616992565b5b6020830191508360208202830111156171fd576171fc616996565b5b9250929050565b5f5f5f5f5f5f6060878903121561721e5761721d61687d565b5b5f87013567ffffffffffffffff81111561723b5761723a616881565b5b61724789828a0161715a565b9650965050602087013567ffffffffffffffff81111561726a57617269616881565b5b61727689828a0161715a565b9450945050604087013567ffffffffffffffff81111561729957617298616881565b5b6172a589828a016171af565b92509250509295509295509295565b5f5f5f606084860312156172cb576172ca61687d565b5b5f84013567ffffffffffffffff8111156172e8576172e7616881565b5b6172f486828701617025565b9350506020617305868287016168a4565b9250506040617316868287016168a4565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61735282617320565b61735c818561732a565b935061736c81856020860161733a565b61737581616ab9565b840191505092915050565b5f6020820190508181035f8301526173988184617348565b905092915050565b5f5f5f606084860312156173b7576173b661687d565b5b5f6173c486828701616a82565b93505060206173d5868287016168a4565b92505060406173e686828701616d98565b9150509250925092565b5f5f83601f8401126174055761740461698e565b5b8235905067ffffffffffffffff81111561742257617421616992565b5b60208301915083602082028301111561743e5761743d616996565b5b9250929050565b5f5f5f5f6060858703121561745d5761745c61687d565b5b5f61746a878288016168a4565b945050602061747b878288016168a4565b935050604085013567ffffffffffffffff81111561749c5761749b616881565b5b6174a8878288016173f0565b925092505092959194509250565b5f5f5f606084860312156174cd576174cc61687d565b5b5f84013567ffffffffffffffff8111156174ea576174e9616881565b5b6174f686828701617025565b9350506020617507868287016168a4565b9250506040617518868287016168fe565b9150509250925092565b5f67ffffffffffffffff82169050919050565b61753e81617522565b8114617548575f5ffd5b50565b5f8135905061755981617535565b92915050565b5f819050919050565b6175718161755f565b811461757b575f5ffd5b50565b5f8135905061758c81617568565b92915050565b5f61010082840312156175a8576175a7616dea565b5b6175b3610100616b27565b90505f6175c2848285016168fe565b5f8301525060206175d58482850161754b565b60208301525060406175e9848285016168fe565b60408301525060606175fd848285016168a4565b6060830152506080617611848285016168fe565b60808301525060a06176258482850161757e565b60a08301525060c082013567ffffffffffffffff81111561764957617648616dee565b5b61765584828501616e75565b60c08301525060e082013567ffffffffffffffff81111561767957617678616dee565b5b61768584828501616e75565b60e08301525092915050565b5f5f604083850312156176a7576176a661687d565b5b5f83013567ffffffffffffffff8111156176c4576176c3616881565b5b6176d085828601617592565b92505060206176e1858286016168a4565b9150509250929050565b5f60208284031215617700576176ff61687d565b5b5f82013567ffffffffffffffff81111561771d5761771c616881565b5b61772984828501617025565b91505092915050565b5f819050919050565b5f61775561775061774b846168b8565b617732565b6168b8565b9050919050565b5f6177668261773b565b9050919050565b5f6177778261775c565b9050919050565b6177878161776d565b82525050565b5f6020820190506177a05f83018461777e565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6177dd82616885565b91506177e883616885565b9250826177f8576177f76177a6565b5b828206905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61783a82616885565b915061784583616885565b925082820190508082111561785d5761785c617803565b5b92915050565b5f61786d82617522565b915061787883617522565b9250828201905067ffffffffffffffff81111561789857617897617803565b5b92915050565b5f6040820190506178b15f830185616c9d565b6178be6020830184616c9d565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b5f61791561791061790b846178f2565b617732565b616885565b9050919050565b617925816178fb565b82525050565b5f6060820190508181035f8301526179438186617348565b90506179526020830185616c9d565b61795f604083018461791c565b949350505050565b5f60608201905061797a5f830186616c9d565b6179876020830185616d23565b6179946040830184616d23565b949350505050565b6179a581616d76565b82525050565b5f6060820190506179be5f83018661799c565b6179cb602083018561799c565b6179d8604083018461799c565b949350505050565b5f6040820190506179f35f830185616d23565b617a006020830184616d23565b9392505050565b5f604082019050617a1a5f830185616c9d565b617a276020830184616d23565b9392505050565b5f606082019050617a415f830186616c9d565b8181036020830152617a538185617348565b90508181036040830152617a678184617348565b9050949350505050565b5f819050919050565b617a8b617a8682616885565b617a71565b82525050565b5f617a9c8284617a7a565b60208201915081905092915050565b5f81519050617ab981617105565b92915050565b5f60208284031215617ad457617ad361687d565b5b5f617ae184828501617aab565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83356001602003843603038112617b3f57617b3e617b17565b5b80840192508235915067ffffffffffffffff821115617b6157617b60617b1b565b5b602083019250600182023603831315617b7d57617b7c617b1f565b5b509250929050565b5f82825260208201905092915050565b5f617ba08385617b85565b9350617bad838584616e26565b617bb683616ab9565b840190509392505050565b5f606082019050617bd45f830187616c9d565b617be16020830186616c9d565b8181036040830152617bf4818486617b95565b905095945050505050565b7f4f7574206f6620626f756e6473000000000000000000000000000000000000005f82015250565b5f617c33600d8361732a565b9150617c3e82617bff565b602082019050919050565b5f6020820190508181035f830152617c6081617c27565b9050919050565b617c7081616a60565b82525050565b5f608082019050617c895f830187617c67565b617c966020830186616c9d565b617ca3604083018561799c565b617cb06060830184616c9d565b95945050505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b617ceb81616885565b82525050565b5f617cfc8383617ce2565b60208301905092915050565b5f602082019050919050565b5f617d1e82617cb9565b617d288185617cc3565b9350617d3383617cd3565b805f5b83811015617d63578151617d4a8882617cf1565b9750617d5583617d08565b925050600181019050617d36565b5085935050505092915050565b5f6040820190508181035f830152617d888185617d14565b9050617d976020830184616d23565b9392505050565b617da7816168d7565b82525050565b617db681617522565b82525050565b617dc58161755f565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f617def82617dcb565b617df98185617dd5565b9350617e0981856020860161733a565b617e1281616ab9565b840191505092915050565b5f61010083015f830151617e335f860182617d9e565b506020830151617e466020860182617dad565b506040830151617e596040860182617d9e565b506060830151617e6c6060860182617ce2565b506080830151617e7f6080860182617d9e565b5060a0830151617e9260a0860182617dbc565b5060c083015184820360c0860152617eaa8282617de5565b91505060e083015184820360e0860152617ec48282617de5565b9150508091505092915050565b5f6040820190508181035f830152617ee98185617e1d565b9050617ef86020830184616c9d565b9392505050565b5f617f0982616885565b9150617f1483616885565b9250828203905081811115617f2c57617f2b617803565b5b92915050565b5f819050919050565b5f617f55617f50617f4b84617f32565b617732565b616885565b9050919050565b617f6581617f3b565b82525050565b5f6060820190508181035f830152617f838186617348565b9050617f926020830185616c9d565b617f9f6040830184617f5c565b949350505050565b5f819050919050565b5f617fca617fc5617fc084617fa7565b617732565b616885565b9050919050565b617fda81617fb0565b82525050565b5f6060820190508181035f830152617ff88186617348565b90506180076020830185616c9d565b6180146040830184617fd1565b949350505050565b5f61802682616a60565b915060ff820361803957618038617803565b5b600182019050919050565b5f81905092915050565b5f61805882617dcb565b6180628185618044565b935061807281856020860161733a565b80840191505092915050565b5f618089828561804e565b9150618095828461804e565b91508190509392505050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b6180e66180e1826180a1565b6180cc565b82525050565b5f6180f7828561804e565b915061810382846180d5565b6001820191508190509392505050565b5f819050919050565b5f61813661813161812c84618113565b617732565b616885565b9050919050565b6181468161811c565b82525050565b5f60a08201905061815f5f830188616c9d565b81810360208301526181718187617348565b90506181806040830186616c9d565b61818d606083018561813d565b61819a608083018461813d565b9695505050505050565b5f60a0820190506181b75f830188616c9d565b81810360208301526181c98187617348565b90506181d86040830186616c9d565b6181e56060830185616c9d565b6181f2608083018461813d565b9695505050505050565b5f60a08201905061820f5f830188616c9d565b81810360208301526182218187617348565b90506182306040830186616c9d565b61823d6060830185616c9d565b61824a6080830184616c9d565b9695505050505050565b5f8160f81b9050919050565b5f61826a82618254565b9050919050565b61828261827d82616a60565b618260565b82525050565b5f8160601b9050919050565b5f61829e82618288565b9050919050565b5f6182af82618294565b9050919050565b6182c76182c2826168d7565b6182a5565b82525050565b5f6182d88288617a7a565b6020820191506182e88287618271565b6001820191506182f88286618271565b60018201915061830882856182b6565b6014820191506183188284617a7a565b6020820191508190509695505050505050565b5f81905092915050565b5f61833f82617320565b618349818561832b565b935061835981856020860161733a565b80840191505092915050565b7f202d3e2000000000000000000000000000000000000000000000000000000000815250565b5f6183968288618335565b91506183a28287618335565b91506183ae8286618335565b91506183ba8285618335565b91506183c582618365565b6004820191506183d58284618335565b91508190509695505050505050565b5f63ffffffff82169050919050565b5f8160e01b9050919050565b5f618409826183f3565b9050919050565b61842161841c826183e4565b6183ff565b82525050565b5f8160c01b9050919050565b5f61843d82618427565b9050919050565b61845561845082617522565b618433565b82525050565b5f819050919050565b6184756184708261755f565b61845b565b82525050565b5f6184868287617a7a565b6020820191506184968286618410565b6004820191506184a68285618444565b6008820191506184b68284618464565b60208201915081905095945050505050565b7f73656c65637400000000000000000000000000000000000000000000000000005f82015250565b5f6184fc60068361732a565b9150618507826184c8565b602082019050919050565b5f6060820190508181035f830152618529816184f0565b90506185386020830185616c9d565b618545604083018461791c565b9392505050565b5f6020820190508181035f830152618563816184f0565b9050919050565b5f60408201905061857d5f830185617c67565b61858a6020830184617c67565b9392505050565b5f6040820190508181035f8301526185a98185617348565b90506185b86020830184617c67565b9392505050565b7f202a200000000000000000000000000000000000000000000000000000000000815250565b5f6185f08285618335565b91506185fb826185bf565b60038201915061860b8284618335565b91508190509392505050565b7f202d200000000000000000000000000000000000000000000000000000000000815250565b5f6186488285618335565b915061865382618617565b6003820191506186638284618335565b91508190509392505050565b7f202b200000000000000000000000000000000000000000000000000000000000815250565b5f6186a08285618335565b91506186ab8261866f565b6003820191506186bb8284618335565b91508190509392505050565b7f205e200000000000000000000000000000000000000000000000000000000000815250565b5f6186f88285618335565b9150618703826186c7565b6003820191506187138284618335565b91508190509392505050565b7f2026200000000000000000000000000000000000000000000000000000000000815250565b5f6187508285618335565b915061875b8261871f565b60038201915061876b8284618335565b91508190509392505050565b7f207c200000000000000000000000000000000000000000000000000000000000815250565b5f6187a88285618335565b91506187b382618777565b6003820191506187c38284618335565b91508190509392505050565b7f202f200000000000000000000000000000000000000000000000000000000000815250565b5f6188008285618335565b915061880b826187cf565b60038201915061881b8284618335565b91508190509392505050565b7f2025200000000000000000000000000000000000000000000000000000000000815250565b5f6188588285618335565b915061886382618827565b6003820191506188738284618335565b91508190509392505050565b7f203c3c2000000000000000000000000000000000000000000000000000000000815250565b5f6188b08285618335565b91506188bb8261887f565b6004820191506188cb8284618335565b91508190509392505050565b7f203e3e2000000000000000000000000000000000000000000000000000000000815250565b5f6189088285618335565b9150618913826188d7565b6004820191506189238284618335565b91508190509392505050565b7f203e3d2000000000000000000000000000000000000000000000000000000000815250565b5f6189608285618335565b915061896b8261892f565b60048201915061897b8284618335565b91508190509392505050565b7f203c3d2000000000000000000000000000000000000000000000000000000000815250565b5f6189b88285618335565b91506189c382618987565b6004820191506189d38284618335565b91508190509392505050565b7f203c200000000000000000000000000000000000000000000000000000000000815250565b5f618a108285618335565b9150618a1b826189df565b600382019150618a2b8284618335565b91508190509392505050565b7f203e200000000000000000000000000000000000000000000000000000000000815250565b5f618a688285618335565b9150618a7382618a37565b600382019150618a838284618335565b91508190509392505050565b7f6d696e2800000000000000000000000000000000000000000000000000000000815250565b7f2c20000000000000000000000000000000000000000000000000000000000000815250565b7f2900000000000000000000000000000000000000000000000000000000000000815250565b5f618b0b82618a8f565b600482019150618b1b8285618335565b9150618b2682618ab5565b600282019150618b368284618335565b9150618b4182618adb565b6001820191508190509392505050565b7f6d61782800000000000000000000000000000000000000000000000000000000815250565b5f618b8182618b51565b600482019150618b918285618335565b9150618b9c82618ab5565b600282019150618bac8284618335565b9150618bb782618adb565b6001820191508190509392505050565b7f203d3d2000000000000000000000000000000000000000000000000000000000815250565b5f618bf88285618335565b9150618c0382618bc7565b600482019150618c138284618335565b91508190509392505050565b7f20213d2000000000000000000000000000000000000000000000000000000000815250565b5f618c508285618335565b9150618c5b82618c1f565b600482019150618c6b8284618335565b91508190509392505050565b7f4648452e61734500000000000000000000000000000000000000000000000000815250565b5f618ca782618c77565b600782019150618cb78284618335565b915081905092915050565b7f2800000000000000000000000000000000000000000000000000000000000000815250565b5f618cf38285618335565b9150618cfe82618cc2565b600182019150618d0e8284618335565b9150618d1982618adb565b6001820191508190509392505050565b7f203f200000000000000000000000000000000000000000000000000000000000815250565b7f203a200000000000000000000000000000000000000000000000000000000000815250565b5f618d808286618335565b9150618d8b82618d29565b600382019150618d9b8285618335565b9150618da682618d4f565b600382019150618db68284618335565b9150819050949350505050565b618dcc8161755f565b82525050565b5f602082019050618de55f830184618dc3565b92915050565b7f2e2e000000000000000000000000000000000000000000000000000000000000815250565b7f295b000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b5f618e688287618335565b9150618e7382618cc2565b600182019150618e838286618335565b9150618e8e82618deb565b600282019150618e9e8285618335565b9150618ea982618e11565b600282019150618eb98284618335565b9150618ec482618e37565b60018201915081905095945050505050565b7f20203d3e20200000000000000000000000000000000000000000000000000000815250565b5f618f078288618335565b9150618f138287618335565b9150618f1f8286618335565b9150618f2b8285618335565b9150618f3682618ed6565b600682019150618f468284618335565b91508190509695505050505050565b5f608082019050618f685f830187618dc3565b618f756020830186617c67565b618f826040830185618dc3565b618f8f6060830184618dc3565b95945050505050565b5f618fa38284618335565b915081905092915050565b5f618fb882616885565b9150618fc383616885565b9250828202618fd181616885565b91508282048414831517618fe857618fe7617803565b5b5092915050565b5f618ff982616885565b91505f820361900b5761900a617803565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfea2646970667358221220b1b525a73d3da74bc529f9fb330a18da72a42175764def7bbcc9a0bba4bc170964736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/MockZkVerifier.ts b/packages/mock-contracts/src/MockZkVerifier.ts index 514b1b80..5ac6b942 100644 --- a/packages/mock-contracts/src/MockZkVerifier.ts +++ b/packages/mock-contracts/src/MockZkVerifier.ts @@ -262,5 +262,5 @@ export const MockZkVerifierArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b506004361061007b575f3560e01c8063772de59611610059578063772de596146100e9578063a2616ba914610119578063a9f046cd14610149578063d2a0693e146101655761007b565b8063267c4ae41461007f5780635946761f1461009d57806366dfcfc6146100cd575b5f5ffd5b610087610195565b6040516100949190610750565b60405180910390f35b6100b760048036038101906100b29190610a4d565b61019d565b6040516100c49190610c95565b60405180910390f35b6100e760048036038101906100e29190610cb5565b6102b5565b005b61010360048036038101906100fe9190610a4d565b61034d565b6040516101109190610d9b565b60405180910390f35b610133600480360381019061012e9190610dbb565b61045b565b6040516101409190610e92565b60405180910390f35b610163600480360381019061015e9190610eb2565b6104bd565b005b61017f600480360381019061017a9190610dbb565b61051b565b60405161018c9190610f37565b60405180910390f35b5f6001905090565b606085518551146101da576040517ff34cfab600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845167ffffffffffffffff8111156101f5576101f461078e565b5b60405190808252806020026020018201604052801561022e57816020015b61021b61070b565b8152602001906001900390816102135790505b5090505f5f90505b85518110156102ab5761028087828151811061025557610254610f50565b5b60200260200101518783815181106102705761026f610f50565b5b602002602001015187878761045b565b82828151811061029357610292610f50565b5b60200260200101819052508080600101915050610236565b5095945050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166315a486fe83836040518363ffffffff1660e01b8152600401610304929190610f7d565b5f604051808303815f87803b15801561031b575f5ffd5b505af115801561032d573d5f5f3e3d5ffd5b5050505060015f5f8282546103429190610fd1565b925050819055505050565b6060855185511461038a576040517ff34cfab600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845167ffffffffffffffff8111156103a5576103a461078e565b5b6040519080825280602002602001820160405280156103d35781602001602082028036833780820191505090505b5090505f5f90505b8551811015610451576104258782815181106103fa576103f9610f50565b5b602002602001015187838151811061041557610414610f50565b5b602002602001015187878761051b565b82828151811061043857610437610f50565b5b60200260200101818152505080806001019150506103db565b5095945050505050565b61046361070b565b5f6104708587868a610533565b905061047c81886102b5565b60405180608001604052808281526020018560ff1681526020018760ff16815260200160405180602001604052805f81525081525091505095945050505050565b5f5f90505b8251811015610516576105098382815181106104e1576104e0610f50565b5b60200260200101518383815181106104fc576104fb610f50565b5b60200260200101516102b5565b80806001019150506104c2565b505050565b5f61052884868589610533565b905095945050505050565b5f5f61053e83610611565b60405160200161054e919061103e565b60405160208183030381529060405290508061057f8773ffffffffffffffffffffffffffffffffffffffff16610611565b604051602001610590929190611054565b6040516020818303038152906040529050805f546040516020016105b49190611097565b604051602081830303815290604052805190602001206040516020016105db9291906110da565b60405160208183030381529060405290505f81805190602001209050610605815f1c86885f610673565b92505050949350505050565b60605f602067ffffffffffffffff81111561062f5761062e61078e565b5b6040519080825280601f01601f1916602001820160405280156106615781602001600182028036833780820191505090505b50905082602082015280915050919050565b5f61ffff80167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106a49190611101565b851690505f8460ff1660086106b985876106cc565b901b179050808217915050949350505050565b5f600160ff8016901c60ff168260ff1616836106e8575f610702565b600160ff8016901c60ff1660ff80166107019190611101565b5b17905092915050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f8115159050919050565b61074a81610736565b82525050565b5f6020820190506107635f830184610741565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6107c48261077e565b810181811067ffffffffffffffff821117156107e3576107e261078e565b5b80604052505050565b5f6107f5610769565b905061080182826107bb565b919050565b5f67ffffffffffffffff8211156108205761081f61078e565b5b602082029050602081019050919050565b5f5ffd5b5f819050919050565b61084781610835565b8114610851575f5ffd5b50565b5f813590506108628161083e565b92915050565b5f61087a61087584610806565b6107ec565b9050808382526020820190506020840283018581111561089d5761089c610831565b5b835b818110156108c657806108b28882610854565b84526020840193505060208101905061089f565b5050509392505050565b5f82601f8301126108e4576108e361077a565b5b81356108f4848260208601610868565b91505092915050565b5f67ffffffffffffffff8211156109175761091661078e565b5b602082029050602081019050919050565b5f60ff82169050919050565b61093d81610928565b8114610947575f5ffd5b50565b5f8135905061095881610934565b92915050565b5f61097061096b846108fd565b6107ec565b9050808382526020820190506020840283018581111561099357610992610831565b5b835b818110156109bc57806109a8888261094a565b845260208401935050602081019050610995565b5050509392505050565b5f82601f8301126109da576109d961077a565b5b81356109ea84826020860161095e565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a1c826109f3565b9050919050565b610a2c81610a12565b8114610a36575f5ffd5b50565b5f81359050610a4781610a23565b92915050565b5f5f5f5f5f60a08688031215610a6657610a65610772565b5b5f86013567ffffffffffffffff811115610a8357610a82610776565b5b610a8f888289016108d0565b955050602086013567ffffffffffffffff811115610ab057610aaf610776565b5b610abc888289016109c6565b9450506040610acd88828901610a39565b9350506060610ade8882890161094a565b9250506080610aef88828901610854565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610b2e81610835565b82525050565b610b3d81610928565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f610b7582610b43565b610b7f8185610b4d565b9350610b8f818560208601610b5d565b610b988161077e565b840191505092915050565b5f608083015f830151610bb85f860182610b25565b506020830151610bcb6020860182610b34565b506040830151610bde6040860182610b34565b5060608301518482036060860152610bf68282610b6b565b9150508091505092915050565b5f610c0e8383610ba3565b905092915050565b5f602082019050919050565b5f610c2c82610afc565b610c368185610b06565b935083602082028501610c4885610b16565b805f5b85811015610c835784840389528151610c648582610c03565b9450610c6f83610c16565b925060208a01995050600181019050610c4b565b50829750879550505050505092915050565b5f6020820190508181035f830152610cad8184610c22565b905092915050565b5f5f60408385031215610ccb57610cca610772565b5b5f610cd885828601610854565b9250506020610ce985828601610854565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f610d278383610b25565b60208301905092915050565b5f602082019050919050565b5f610d4982610cf3565b610d538185610cfd565b9350610d5e83610d0d565b805f5b83811015610d8e578151610d758882610d1c565b9750610d8083610d33565b925050600181019050610d61565b5085935050505092915050565b5f6020820190508181035f830152610db38184610d3f565b905092915050565b5f5f5f5f5f60a08688031215610dd457610dd3610772565b5b5f610de188828901610854565b9550506020610df28882890161094a565b9450506040610e0388828901610a39565b9350506060610e148882890161094a565b9250506080610e2588828901610854565b9150509295509295909350565b5f608083015f830151610e475f860182610b25565b506020830151610e5a6020860182610b34565b506040830151610e6d6040860182610b34565b5060608301518482036060860152610e858282610b6b565b9150508091505092915050565b5f6020820190508181035f830152610eaa8184610e32565b905092915050565b5f5f60408385031215610ec857610ec7610772565b5b5f83013567ffffffffffffffff811115610ee557610ee4610776565b5b610ef1858286016108d0565b925050602083013567ffffffffffffffff811115610f1257610f11610776565b5b610f1e858286016108d0565b9150509250929050565b610f3181610835565b82525050565b5f602082019050610f4a5f830184610f28565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f604082019050610f905f830185610f28565b610f9d6020830184610f28565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610fdb82610835565b9150610fe683610835565b9250828201905080821115610ffe57610ffd610fa4565b5b92915050565b5f81905092915050565b5f61101882610b43565b6110228185611004565b9350611032818560208601610b5d565b80840191505092915050565b5f611049828461100e565b915081905092915050565b5f61105f828561100e565b915061106b828461100e565b91508190509392505050565b5f819050919050565b61109161108c82610835565b611077565b82525050565b5f6110a28284611080565b60208201915081905092915050565b5f819050919050565b5f819050919050565b6110d46110cf826110b1565b6110ba565b82525050565b5f6110e5828561100e565b91506110f182846110c3565b6020820191508190509392505050565b5f61110b82610835565b915061111683610835565b925082820390508181111561112e5761112d610fa4565b5b9291505056fea26469706673582212204ba923043ce29591b7adc03799bc10ed8ad01de2292597489dc1f8fb79510c4864736f6c63430008210033', + '0x608060405234801561000f575f5ffd5b506004361061007b575f3560e01c8063772de59611610059578063772de596146100e9578063a2616ba914610119578063a9f046cd14610149578063d2a0693e146101655761007b565b8063267c4ae41461007f5780635946761f1461009d57806366dfcfc6146100cd575b5f5ffd5b610087610195565b6040516100949190610750565b60405180910390f35b6100b760048036038101906100b29190610a4d565b61019d565b6040516100c49190610c95565b60405180910390f35b6100e760048036038101906100e29190610cb5565b6102b5565b005b61010360048036038101906100fe9190610a4d565b61034d565b6040516101109190610d9b565b60405180910390f35b610133600480360381019061012e9190610dbb565b61045b565b6040516101409190610e92565b60405180910390f35b610163600480360381019061015e9190610eb2565b6104bd565b005b61017f600480360381019061017a9190610dbb565b61051b565b60405161018c9190610f37565b60405180910390f35b5f6001905090565b606085518551146101da576040517ff34cfab600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845167ffffffffffffffff8111156101f5576101f461078e565b5b60405190808252806020026020018201604052801561022e57816020015b61021b61070b565b8152602001906001900390816102135790505b5090505f5f90505b85518110156102ab5761028087828151811061025557610254610f50565b5b60200260200101518783815181106102705761026f610f50565b5b602002602001015187878761045b565b82828151811061029357610292610f50565b5b60200260200101819052508080600101915050610236565b5095945050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166315a486fe83836040518363ffffffff1660e01b8152600401610304929190610f7d565b5f604051808303815f87803b15801561031b575f5ffd5b505af115801561032d573d5f5f3e3d5ffd5b5050505060015f5f8282546103429190610fd1565b925050819055505050565b6060855185511461038a576040517ff34cfab600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845167ffffffffffffffff8111156103a5576103a461078e565b5b6040519080825280602002602001820160405280156103d35781602001602082028036833780820191505090505b5090505f5f90505b8551811015610451576104258782815181106103fa576103f9610f50565b5b602002602001015187838151811061041557610414610f50565b5b602002602001015187878761051b565b82828151811061043857610437610f50565b5b60200260200101818152505080806001019150506103db565b5095945050505050565b61046361070b565b5f6104708587868a610533565b905061047c81886102b5565b60405180608001604052808281526020018560ff1681526020018760ff16815260200160405180602001604052805f81525081525091505095945050505050565b5f5f90505b8251811015610516576105098382815181106104e1576104e0610f50565b5b60200260200101518383815181106104fc576104fb610f50565b5b60200260200101516102b5565b80806001019150506104c2565b505050565b5f61052884868589610533565b905095945050505050565b5f5f61053e83610611565b60405160200161054e919061103e565b60405160208183030381529060405290508061057f8773ffffffffffffffffffffffffffffffffffffffff16610611565b604051602001610590929190611054565b6040516020818303038152906040529050805f546040516020016105b49190611097565b604051602081830303815290604052805190602001206040516020016105db9291906110da565b60405160208183030381529060405290505f81805190602001209050610605815f1c86885f610673565b92505050949350505050565b60605f602067ffffffffffffffff81111561062f5761062e61078e565b5b6040519080825280601f01601f1916602001820160405280156106615781602001600182028036833780820191505090505b50905082602082015280915050919050565b5f61ffff80167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106a49190611101565b851690505f8460ff1660086106b985876106cc565b901b179050808217915050949350505050565b5f600160ff8016901c60ff168260ff1616836106e8575f610702565b600160ff8016901c60ff1660ff80166107019190611101565b5b17905092915050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f8115159050919050565b61074a81610736565b82525050565b5f6020820190506107635f830184610741565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6107c48261077e565b810181811067ffffffffffffffff821117156107e3576107e261078e565b5b80604052505050565b5f6107f5610769565b905061080182826107bb565b919050565b5f67ffffffffffffffff8211156108205761081f61078e565b5b602082029050602081019050919050565b5f5ffd5b5f819050919050565b61084781610835565b8114610851575f5ffd5b50565b5f813590506108628161083e565b92915050565b5f61087a61087584610806565b6107ec565b9050808382526020820190506020840283018581111561089d5761089c610831565b5b835b818110156108c657806108b28882610854565b84526020840193505060208101905061089f565b5050509392505050565b5f82601f8301126108e4576108e361077a565b5b81356108f4848260208601610868565b91505092915050565b5f67ffffffffffffffff8211156109175761091661078e565b5b602082029050602081019050919050565b5f60ff82169050919050565b61093d81610928565b8114610947575f5ffd5b50565b5f8135905061095881610934565b92915050565b5f61097061096b846108fd565b6107ec565b9050808382526020820190506020840283018581111561099357610992610831565b5b835b818110156109bc57806109a8888261094a565b845260208401935050602081019050610995565b5050509392505050565b5f82601f8301126109da576109d961077a565b5b81356109ea84826020860161095e565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a1c826109f3565b9050919050565b610a2c81610a12565b8114610a36575f5ffd5b50565b5f81359050610a4781610a23565b92915050565b5f5f5f5f5f60a08688031215610a6657610a65610772565b5b5f86013567ffffffffffffffff811115610a8357610a82610776565b5b610a8f888289016108d0565b955050602086013567ffffffffffffffff811115610ab057610aaf610776565b5b610abc888289016109c6565b9450506040610acd88828901610a39565b9350506060610ade8882890161094a565b9250506080610aef88828901610854565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610b2e81610835565b82525050565b610b3d81610928565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f610b7582610b43565b610b7f8185610b4d565b9350610b8f818560208601610b5d565b610b988161077e565b840191505092915050565b5f608083015f830151610bb85f860182610b25565b506020830151610bcb6020860182610b34565b506040830151610bde6040860182610b34565b5060608301518482036060860152610bf68282610b6b565b9150508091505092915050565b5f610c0e8383610ba3565b905092915050565b5f602082019050919050565b5f610c2c82610afc565b610c368185610b06565b935083602082028501610c4885610b16565b805f5b85811015610c835784840389528151610c648582610c03565b9450610c6f83610c16565b925060208a01995050600181019050610c4b565b50829750879550505050505092915050565b5f6020820190508181035f830152610cad8184610c22565b905092915050565b5f5f60408385031215610ccb57610cca610772565b5b5f610cd885828601610854565b9250506020610ce985828601610854565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f610d278383610b25565b60208301905092915050565b5f602082019050919050565b5f610d4982610cf3565b610d538185610cfd565b9350610d5e83610d0d565b805f5b83811015610d8e578151610d758882610d1c565b9750610d8083610d33565b925050600181019050610d61565b5085935050505092915050565b5f6020820190508181035f830152610db38184610d3f565b905092915050565b5f5f5f5f5f60a08688031215610dd457610dd3610772565b5b5f610de188828901610854565b9550506020610df28882890161094a565b9450506040610e0388828901610a39565b9350506060610e148882890161094a565b9250506080610e2588828901610854565b9150509295509295909350565b5f608083015f830151610e475f860182610b25565b506020830151610e5a6020860182610b34565b506040830151610e6d6040860182610b34565b5060608301518482036060860152610e858282610b6b565b9150508091505092915050565b5f6020820190508181035f830152610eaa8184610e32565b905092915050565b5f5f60408385031215610ec857610ec7610772565b5b5f83013567ffffffffffffffff811115610ee557610ee4610776565b5b610ef1858286016108d0565b925050602083013567ffffffffffffffff811115610f1257610f11610776565b5b610f1e858286016108d0565b9150509250929050565b610f3181610835565b82525050565b5f602082019050610f4a5f830184610f28565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f604082019050610f905f830185610f28565b610f9d6020830184610f28565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610fdb82610835565b9150610fe683610835565b9250828201905080821115610ffe57610ffd610fa4565b5b92915050565b5f81905092915050565b5f61101882610b43565b6110228185611004565b9350611032818560208601610b5d565b80840191505092915050565b5f611049828461100e565b915081905092915050565b5f61105f828561100e565b915061106b828461100e565b91508190509392505050565b5f819050919050565b61109161108c82610835565b611077565b82525050565b5f6110a28284611080565b60208201915081905092915050565b5f819050919050565b5f819050919050565b6110d46110cf826110b1565b6110ba565b82525050565b5f6110e5828561100e565b91506110f182846110c3565b6020820191508190509392505050565b5f61110b82610835565b915061111683610835565b925082820390508181111561112e5761112d610fa4565b5b9291505056fea2646970667358221220f2262abbfb37de21cb5600502c612f300af20a5c6568827d0b585d251c467e6864736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/TestBed.ts b/packages/mock-contracts/src/TestBed.ts index 724d2a09..60cb5ee9 100644 --- a/packages/mock-contracts/src/TestBed.ts +++ b/packages/mock-contracts/src/TestBed.ts @@ -55,7 +55,7 @@ export const TestBedArtifact = { outputs: [ { name: '', - type: 'uint256', + type: 'bytes32', internalType: 'euint32', }, ], @@ -80,7 +80,7 @@ export const TestBedArtifact = { inputs: [ { name: 'input1', - type: 'uint256', + type: 'bytes32', internalType: 'euint32', }, ], @@ -99,7 +99,7 @@ export const TestBedArtifact = { inputs: [ { name: 'input1', - type: 'uint256', + type: 'bytes32', internalType: 'euint32', }, ], @@ -284,5 +284,5 @@ export const TestBedArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b50600436106100b2575f3560e01c806384f091db1161006f57806384f091db1461016757806384ff25c614610183578063b5872e8c1461019f578063d09de08a146101bb578063d7a0faa2146101c5578063f6bc7f3f146101e1576100b2565b806319d8a05b146100b6578063267c4ae4146100d45780633983d430146100f2578063458693c9146100fc578063647096091461012d57806367c6517414610149575b5f5ffd5b6100be610211565b6040516100cb9190610eef565b60405180910390f35b6100dc610216565b6040516100e99190610f22565b60405180910390f35b6100fa61021e565b005b61011660048036038101906101119190610f76565b61022a565b604051610124929190610fbf565b60405180910390f35b6101476004803603810190610142919061121b565b61023e565b005b610151610293565b60405161015e9190611271565b60405180910390f35b610181600480360381019061017c919061121b565b610299565b005b61019d6004803603810190610198919061121b565b6102c8565b005b6101b960048036038101906101b4919061121b565b6102f7565b005b6101c3610324565b005b6101df60048036038101906101da919061128a565b610353565b005b6101fb60048036038101906101f69190610f76565b610380565b60405161020891906112b5565b60405180910390f35b5f5481565b5f6001905090565b6102285f54610391565b565b5f5f610235836103b7565b91509150915091565b5f610248826103d5565b90505f610268610259835f54610448565b836102635f610491565b6104a3565b90506102755f5482610505565b5f819055506102845f5461054e565b61028e5f546105cd565b505050565b60015481565b6102ac5f546102a7836103d5565b61064c565b5f819055506102bb5f5461054e565b6102c55f546105cd565b50565b6102db5f546102d6836103d5565b610695565b5f819055506102ea5f5461054e565b6102f45f546105cd565b50565b610300816103d5565b5f819055505f546001819055506103175f5461054e565b6103215f546105cd565b50565b6103385f546103336001610491565b610695565b5f819055506103475f5461054e565b6103515f546105cd565b565b61035c81610491565b5f819055505f546001819055506103735f5461054e565b61037d5f546105cd565b50565b5f61038a826106de565b9050919050565b61039a816106ef565b6103aa576103a75f610491565b90505b6103b381610700565b5050565b5f5f5f5f6103c485610785565b915091508181935093505050915091565b5f5f600490508060ff16836040015160ff161461042f578260400151816040517f67cf30710000000000000000000000000000000000000000000000000000000081526004016104269291906112dd565b60405180910390fd5b61044061043b8461081b565b61085d565b915050919050565b5f610452836106ef565b6104625761045f5f610491565b92505b61046b826106ef565b61047b576104785f610491565b91505b6104896004848460136108f4565b905092915050565b5f61049c825f6109e3565b9050919050565b5f6104ad846109fd565b6104bd576104ba5f610a0e565b93505b6104c6836106ef565b6104d6576104d35f610491565b92505b6104df826106ef565b6104ef576104ec5f610491565b91505b6104fc6004858585610a20565b90509392505050565b5f61050f836106ef565b61051f5761051c5f610491565b92505b610528826106ef565b610538576105355f610491565b91505b6105466004848460076108f4565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c82306040518363ffffffff1660e01b815260040161059d929190611343565b5f604051808303815f87803b1580156105b4575f5ffd5b505af11580156105c6573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c82336040518363ffffffff1660e01b815260040161061c929190611343565b5f604051808303815f87803b158015610633575f5ffd5b505af1158015610645573d5f5f3e3d5ffd5b5050505050565b5f610656836106ef565b610666576106635f610491565b92505b61066f826106ef565b61067f5761067c5f610491565b91505b61068d60048484600f6108f4565b905092915050565b5f61069f836106ef565b6106af576106ac5f610491565b92505b6106b8826106ef565b6106c8576106c55f610491565b91505b6106d66004848460086108f4565b905092915050565b5f6106e882610b11565b9050919050565b5f6106f982610ba5565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16630828982783336040518363ffffffff1660e01b8152600401610750929190611343565b5f604051808303815f87803b158015610767575f5ffd5b505af1158015610779573d5f5f3e3d5ffd5b50505050819050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9846040518263ffffffff1660e01b81526004016107d49190611271565b6040805180830381865afa1580156107ee573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081291906113a8565b91509150915091565b610823610e82565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016108ad9291906114c4565b6020604051808303815f875af11580156108c9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108ed91906114f2565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd86846109318888610bb1565b5f67ffffffffffffffff81111561094b5761094a610ffa565b5b6040519080825280602002602001820160405280156109795781602001602082028036833780820191505090505b506040518563ffffffff1660e01b81526004016109999493929190611638565b6020604051808303815f875af11580156109b5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d991906114f2565b9050949350505050565b5f5f6109f184600485610c4b565b90508091505092915050565b5f610a0782610ba5565b9050919050565b5f610a19825f610d46565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610a5f888888610d6f565b5f67ffffffffffffffff811115610a7957610a78610ffa565b5b604051908082528060200260200182016040528015610aa75781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610ac79493929190611638565b6020604051808303815f875af1158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0791906114f2565b9050949350505050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f836040518263ffffffff1660e01b8152600401610b5f9190611271565b602060405180830381865afa158015610b7a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b9e91906114f2565b9050919050565b5f5f8214159050919050565b60605f600267ffffffffffffffff811115610bcf57610bce610ffa565b5b604051908082528060200260200182016040528015610bfd5781602001602082028036833780820191505090505b50905083815f81518110610c1457610c13611689565b5b6020026020010181815250508281600181518110610c3557610c34611689565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610c9957610c98610ffa565b5b604051908082528060200260200182016040528015610cc75781602001602082028036833780820191505090505b50610cde898960ff16610cd98a610e2b565b610d6f565b6040518563ffffffff1660e01b8152600401610cfd9493929190611638565b6020604051808303815f875af1158015610d19573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d3d91906114f2565b90509392505050565b5f5f5f90508315610d5657600190505b5f610d62825f86610c4b565b9050809250505092915050565b60605f600367ffffffffffffffff811115610d8d57610d8c610ffa565b5b604051908082528060200260200182016040528015610dbb5781602001602082028036833780820191505090505b50905084815f81518110610dd257610dd1611689565b5b6020026020010181815250508381600181518110610df357610df2611689565b5b6020026020010181815250508281600281518110610e1457610e13611689565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610e7457816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610e6b91906116d1565b60405180910390fd5b8163ffffffff169050919050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f819050919050565b5f819050919050565b5f610ed9610ed4610ecf84610ead565b610eb6565b610ead565b9050919050565b610ee981610ebf565b82525050565b5f602082019050610f025f830184610ee0565b92915050565b5f8115159050919050565b610f1c81610f08565b82525050565b5f602082019050610f355f830184610f13565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b610f5581610ead565b8114610f5f575f5ffd5b50565b5f81359050610f7081610f4c565b92915050565b5f60208284031215610f8b57610f8a610f44565b5b5f610f9884828501610f62565b91505092915050565b5f63ffffffff82169050919050565b610fb981610fa1565b82525050565b5f604082019050610fd25f830185610fb0565b610fdf6020830184610f13565b9392505050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61103082610fea565b810181811067ffffffffffffffff8211171561104f5761104e610ffa565b5b80604052505050565b5f611061610f3b565b905061106d8282611027565b919050565b5f5ffd5b61107f81610ead565b8114611089575f5ffd5b50565b5f8135905061109a81611076565b92915050565b5f60ff82169050919050565b6110b5816110a0565b81146110bf575f5ffd5b50565b5f813590506110d0816110ac565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156110f8576110f7610ffa565b5b61110182610fea565b9050602081019050919050565b828183375f83830152505050565b5f61112e611129846110de565b611058565b90508281526020810184848401111561114a576111496110da565b5b61115584828561110e565b509392505050565b5f82601f830112611171576111706110d6565b5b813561118184826020860161111c565b91505092915050565b5f6080828403121561119f5761119e610fe6565b5b6111a96080611058565b90505f6111b88482850161108c565b5f8301525060206111cb848285016110c2565b60208301525060406111df848285016110c2565b604083015250606082013567ffffffffffffffff81111561120357611202611072565b5b61120f8482850161115d565b60608301525092915050565b5f602082840312156112305761122f610f44565b5b5f82013567ffffffffffffffff81111561124d5761124c610f48565b5b6112598482850161118a565b91505092915050565b61126b81610ead565b82525050565b5f6020820190506112845f830184611262565b92915050565b5f6020828403121561129f5761129e610f44565b5b5f6112ac8482850161108c565b91505092915050565b5f6020820190506112c85f830184610fb0565b92915050565b6112d7816110a0565b82525050565b5f6040820190506112f05f8301856112ce565b6112fd60208301846112ce565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61132d82611304565b9050919050565b61133d81611323565b82525050565b5f6040820190506113565f830185611262565b6113636020830184611334565b9392505050565b5f8151905061137881611076565b92915050565b61138781610f08565b8114611391575f5ffd5b50565b5f815190506113a28161137e565b92915050565b5f5f604083850312156113be576113bd610f44565b5b5f6113cb8582860161136a565b92505060206113dc85828601611394565b9150509250929050565b6113ef81610ead565b82525050565b6113fe816110a0565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61143682611404565b611440818561140e565b935061145081856020860161141e565b61145981610fea565b840191505092915050565b5f608083015f8301516114795f8601826113e6565b50602083015161148c60208601826113f5565b50604083015161149f60408601826113f5565b50606083015184820360608601526114b7828261142c565b9150508091505092915050565b5f6040820190508181035f8301526114dc8185611464565b90506114eb6020830184611334565b9392505050565b5f6020828403121561150757611506610f44565b5b5f6115148482850161136a565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020811061155b5761155a61151d565b5b50565b5f81905061156b8261154a565b919050565b5f61157a8261155e565b9050919050565b61158a81611570565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f6115c483836113e6565b60208301905092915050565b5f602082019050919050565b5f6115e682611590565b6115f0818561159a565b93506115fb836115aa565b805f5b8381101561162b57815161161288826115b9565b975061161d836115d0565b9250506001810190506115fe565b5085935050505092915050565b5f60808201905061164b5f8301876112ce565b6116586020830186611581565b818103604083015261166a81856115dc565b9050818103606083015261167e81846115dc565b905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b6116cb816116b6565b82525050565b5f6020820190506116e45f8301846116c2565b9291505056fea2646970667358221220758d6ba5fabe26207a9eeb269ab2354286adbb7560142c08897a08e8c702793f64736f6c63430008210033', + '0x608060405234801561000f575f5ffd5b50600436106100b2575f3560e01c806367c651741161006f57806367c651741461017957806384f091db1461019757806384ff25c6146101b3578063b5872e8c146101cf578063d09de08a146101eb578063d7a0faa2146101f5576100b2565b80631292f65a146100b657806319d8a05b146100e6578063260ec88914610104578063267c4ae4146101355780633983d43014610153578063647096091461015d575b5f5ffd5b6100d060048036038101906100cb9190610fd4565b610211565b6040516100dd919061101d565b60405180910390f35b6100ee610222565b6040516100fb9190611056565b60405180910390f35b61011e60048036038101906101199190610fd4565b610227565b60405161012c929190611089565b60405180910390f35b61013d61023b565b60405161014a91906110b0565b60405180910390f35b61015b610243565b005b61017760048036038101906101729190611307565b61024f565b005b6101816102a4565b60405161018e919061135d565b60405180910390f35b6101b160048036038101906101ac9190611307565b6102aa565b005b6101cd60048036038101906101c89190611307565b6102d9565b005b6101e960048036038101906101e49190611307565b610308565b005b6101f3610337565b005b61020f600480360381019061020a9190611376565b610366565b005b5f61021b82610395565b9050919050565b5f5481565b5f5f610232836103a6565b91509150915091565b5f6001905090565b61024d5f546103c4565b565b5f610259826103ea565b90505f61027961026a835f54610412565b836102745f61045b565b61046d565b90506102865f54826104cf565b5f819055506102955f54610518565b61029f5f54610599565b505050565b60015481565b6102bd5f546102b8836103ea565b61061a565b5f819055506102cc5f54610518565b6102d65f54610599565b50565b6102ec5f546102e7836103ea565b610663565b5f819055506102fb5f54610518565b6103055f54610599565b50565b610311816103ea565b5f819055505f545f1c60018190555061032a5f54610518565b6103345f54610599565b50565b61034b5f54610346600161045b565b610663565b5f8190555061035a5f54610518565b6103645f54610599565b565b61036f8161045b565b5f819055505f545f1c6001819055506103885f54610518565b6103925f54610599565b50565b5f61039f826106ac565b9050919050565b5f5f5f5f6103b385610742565b915091508181935093505050915091565b6103cd816107da565b6103dd576103da5f61045b565b90505b6103e6816107eb565b5050565b5f6103fa82604001516004610872565b61040b610406836108c2565b610904565b9050919050565b5f61041c836107da565b61042c576104295f61045b565b92505b610435826107da565b610445576104425f61045b565b91505b61045360048484601361099d565b905092915050565b5f610466825f610a8e565b9050919050565b5f61047784610aa8565b610487576104845f610ab9565b93505b610490836107da565b6104a05761049d5f61045b565b92505b6104a9826107da565b6104b9576104b65f61045b565b91505b6104c66004858585610acb565b90509392505050565b5f6104d9836107da565b6104e9576104e65f61045b565b92505b6104f2826107da565b610502576104ff5f61045b565b91505b61051060048484600761099d565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c306040518363ffffffff1660e01b81526004016105699291906113e0565b5f604051808303815f87803b158015610580575f5ffd5b505af1158015610592573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c336040518363ffffffff1660e01b81526004016105ea9291906113e0565b5f604051808303815f87803b158015610601575f5ffd5b505af1158015610613573d5f5f3e3d5ffd5b5050505050565b5f610624836107da565b610634576106315f61045b565b92505b61063d826107da565b61064d5761064a5f61045b565b91505b61065b60048484600f61099d565b905092915050565b5f61066d836107da565b61067d5761067a5f61045b565b92505b610686826107da565b610696576106935f61045b565b91505b6106a460048484600861099d565b905092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f835f1c6040518263ffffffff1660e01b81526004016106fc919061135d565b602060405180830381865afa158015610717573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073b919061141b565b9050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9845f1c6040518263ffffffff1660e01b8152600401610793919061135d565b6040805180830381865afa1580156107ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d19190611470565b91509150915091565b5f6107e482610bbe565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166308289827835f1c336040518363ffffffff1660e01b815260040161083d9291906113e0565b5f604051808303815f87803b158015610854575f5ffd5b505af1158015610866573d5f5f3e3d5ffd5b50505050819050919050565b8060ff168260ff16146108be5781816040517f67cf30710000000000000000000000000000000000000000000000000000000081526004016108b59291906114bd565b60405180910390fd5b5050565b6108ca610f65565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016109549291906115c2565b6020604051808303815f875af1158015610970573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610994919061141b565b5f1b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd86846109da8888610bcc565b5f67ffffffffffffffff8111156109f4576109f36110dd565b5b604051908082528060200260200182016040528015610a225781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610a42949392919061170b565b6020604051808303815f875af1158015610a5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a82919061141b565b5f1b9050949350505050565b5f5f610a9c84600485610c6a565b90508091505092915050565b5f610ab282610bbe565b9050919050565b5f610ac4825f610d67565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610b0a888888610d90565b5f67ffffffffffffffff811115610b2457610b236110dd565b5b604051908082528060200260200182016040528015610b525781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610b72949392919061170b565b6020604051808303815f875af1158015610b8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb2919061141b565b5f1b9050949350505050565b5f5f5f1b8214159050919050565b60605f600267ffffffffffffffff811115610bea57610be96110dd565b5b604051908082528060200260200182016040528015610c185781602001602082028036833780820191505090505b509050835f1c815f81518110610c3157610c3061175c565b5b602002602001018181525050825f1c81600181518110610c5457610c5361175c565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610cb857610cb76110dd565b5b604051908082528060200260200182016040528015610ce65781602001602082028036833780820191505090505b50610cfd898960ff16610cf88a610e52565b610ea9565b6040518563ffffffff1660e01b8152600401610d1c949392919061170b565b6020604051808303815f875af1158015610d38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5c919061141b565b5f1b90509392505050565b5f5f5f90508315610d7757600190505b5f610d83825f86610c6a565b9050809250505092915050565b60605f600367ffffffffffffffff811115610dae57610dad6110dd565b5b604051908082528060200260200182016040528015610ddc5781602001602082028036833780820191505090505b509050845f1c815f81518110610df557610df461175c565b5b602002602001018181525050835f1c81600181518110610e1857610e1761175c565b5b602002602001018181525050825f1c81600281518110610e3b57610e3a61175c565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610e9b57816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610e9291906117a4565b60405180910390fd5b8163ffffffff169050919050565b60605f600367ffffffffffffffff811115610ec757610ec66110dd565b5b604051908082528060200260200182016040528015610ef55781602001602082028036833780820191505090505b50905084815f81518110610f0c57610f0b61175c565b5b6020026020010181815250508381600181518110610f2d57610f2c61175c565b5b6020026020010181815250508281600281518110610f4e57610f4d61175c565b5b602002602001018181525050809150509392505050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610fb381610fa1565b8114610fbd575f5ffd5b50565b5f81359050610fce81610faa565b92915050565b5f60208284031215610fe957610fe8610f99565b5b5f610ff684828501610fc0565b91505092915050565b5f63ffffffff82169050919050565b61101781610fff565b82525050565b5f6020820190506110305f83018461100e565b92915050565b5f61104082610fa1565b9050919050565b61105081611036565b82525050565b5f6020820190506110695f830184611047565b92915050565b5f8115159050919050565b6110838161106f565b82525050565b5f60408201905061109c5f83018561100e565b6110a9602083018461107a565b9392505050565b5f6020820190506110c35f83018461107a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611113826110cd565b810181811067ffffffffffffffff82111715611132576111316110dd565b5b80604052505050565b5f611144610f90565b9050611150828261110a565b919050565b5f5ffd5b5f819050919050565b61116b81611159565b8114611175575f5ffd5b50565b5f8135905061118681611162565b92915050565b5f60ff82169050919050565b6111a18161118c565b81146111ab575f5ffd5b50565b5f813590506111bc81611198565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156111e4576111e36110dd565b5b6111ed826110cd565b9050602081019050919050565b828183375f83830152505050565b5f61121a611215846111ca565b61113b565b905082815260208101848484011115611236576112356111c6565b5b6112418482856111fa565b509392505050565b5f82601f83011261125d5761125c6111c2565b5b813561126d848260208601611208565b91505092915050565b5f6080828403121561128b5761128a6110c9565b5b611295608061113b565b90505f6112a484828501611178565b5f8301525060206112b7848285016111ae565b60208301525060406112cb848285016111ae565b604083015250606082013567ffffffffffffffff8111156112ef576112ee611155565b5b6112fb84828501611249565b60608301525092915050565b5f6020828403121561131c5761131b610f99565b5b5f82013567ffffffffffffffff81111561133957611338610f9d565b5b61134584828501611276565b91505092915050565b61135781611159565b82525050565b5f6020820190506113705f83018461134e565b92915050565b5f6020828403121561138b5761138a610f99565b5b5f61139884828501611178565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113ca826113a1565b9050919050565b6113da816113c0565b82525050565b5f6040820190506113f35f83018561134e565b61140060208301846113d1565b9392505050565b5f8151905061141581611162565b92915050565b5f602082840312156114305761142f610f99565b5b5f61143d84828501611407565b91505092915050565b61144f8161106f565b8114611459575f5ffd5b50565b5f8151905061146a81611446565b92915050565b5f5f6040838503121561148657611485610f99565b5b5f61149385828601611407565b92505060206114a48582860161145c565b9150509250929050565b6114b78161118c565b82525050565b5f6040820190506114d05f8301856114ae565b6114dd60208301846114ae565b9392505050565b6114ed81611159565b82525050565b6114fc8161118c565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61153482611502565b61153e818561150c565b935061154e81856020860161151c565b611557816110cd565b840191505092915050565b5f608083015f8301516115775f8601826114e4565b50602083015161158a60208601826114f3565b50604083015161159d60408601826114f3565b50606083015184820360608601526115b5828261152a565b9150508091505092915050565b5f6040820190508181035f8301526115da8185611562565b90506115e960208301846113d1565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020811061162e5761162d6115f0565b5b50565b5f81905061163e8261161d565b919050565b5f61164d82611631565b9050919050565b61165d81611643565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61169783836114e4565b60208301905092915050565b5f602082019050919050565b5f6116b982611663565b6116c3818561166d565b93506116ce8361167d565b805f5b838110156116fe5781516116e5888261168c565b97506116f0836116a3565b9250506001810190506116d1565b5085935050505092915050565b5f60808201905061171e5f8301876114ae565b61172b6020830186611654565b818103604083015261173d81856116af565b9050818103606083015261175181846116af565b905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b61179e81611789565b82525050565b5f6020820190506117b75f830184611795565b9291505056fea264697066735822122073ac55a0782990f2903a9db8268d740b09bc94dd31b938921048980bcec8c1e464736f6c634300081c0033', } satisfies MockArtifact; From 15f8646be87cbb5d2aae0e6cb1b2669d5591db2a Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 14:02:38 +0200 Subject: [PATCH 10/24] chore: high-level section for mock-contracts --- packages/mock-contracts/README.md | 61 +++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/packages/mock-contracts/README.md b/packages/mock-contracts/README.md index 2f3308f8..2d96dde5 100644 --- a/packages/mock-contracts/README.md +++ b/packages/mock-contracts/README.md @@ -1,4 +1,4 @@ -# @fhenixprotocol/cofhe-mock-contracts [![NPM Package][npm-badge]][npm] [![License: MIT][license-badge]][license] +# cofhe/mock-contracts [![NPM Package][npm-badge]][npm] [![License: MIT][license-badge]][license] [npm]: https://www.npmjs.com/package/@fhenixprotocol/cofhe-mock-contracts [npm-badge]: https://img.shields.io/npm/v/@fhenixprotocol/cofhe-mock-contracts.svg @@ -34,6 +34,63 @@ forge install fhenixprotocol/cofhe-mock-contracts ## Usages and Integrations +### Who is this for? + +This package is intended for **developers building and testing CoFHE-enabled applications and smart contracts**. + +Use these mocks when you want to: + +- Run **local tests** without depending on the real CoFHE coprocessor infrastructure. +- Debug flows end-to-end (encrypt → submit → operate → decrypt) with fast iteration. +- Assert on results deterministically in CI. + +Do **not** use these mocks for production deployments: they intentionally make testing convenient (e.g. storing plaintext on-chain for inspection) and therefore **do not provide real confidentiality guarantees**. + +### Hardhat integration vs Foundry integration + +Both integrations use the same underlying mock contracts, but they differ in **how mocks get deployed** and **how you interact with them**. + +#### Hardhat (recommended for TS/SDK + Solidity tests) + +Use this when you are already using **Hardhat** and/or want to run the **TypeScript SDK (`@cofhe/sdk`)** against a local chain. + +- The `cofhesdk/hardhat-plugin` watches Hardhat `node` and `test` tasks. +- It automatically deploys the mocks to the Hardhat network at fixed addresses. +- The `cofheClient` (created with `createCofheClient(...)`) detects the mocks and routes CoFHE actions to them. + +Minimal setup: + +```ts +// hardhat.config.ts +import 'cofhe-hardhat-plugin'; + +export default { + cofhe: { + logMocks: true, // optional + }, +}; +``` + +Run: + +```bash +npx hardhat test +# or +npx hardhat node +``` + +If you want to assert on plaintext values in Hardhat tests, the plugin exposes helpers like `mock_expectPlaintext(...)` (see the hardhat-plugin README). + +#### Foundry (recommended for Solidity-only tests) + +Use this when you are writing tests in **Solidity** and running them with `forge test`. + +- You typically inherit from the abstract `CoFheTest` helper to deploy/setup the necessary FHE mock environment. +- You use helper methods to create encrypted inputs and assert their underlying values. + +> **Important**: You must set `isolate = true` in your `foundry.toml`. Without this setting, some variables may be used without proper permission checks, which will cause failures on production chains. + + `@cofhe/sdk` is designed to work with mock contracts in a testing / hardhat environment. `cofhesdk/hardhat-plugin` deploys the mock contracts in this repo, and the `cofheClient` detects a testnet chain and interacts correctly using the mocks rather than the true CoFHE coprocessor. When installed and imported in the `hardhat.config.ts`, `cofhesdk/hardhat-plugin` will watch for Hardhat `node` and `test` tasks, and will deploy the mocks to the hardhat testnet chain at fixed addresses. @@ -83,8 +140,6 @@ When working with the mocks, the `cofheClient` will instead query the `MockQuery ### Using Foundry -> **Important**: You must set `isolate = true` in your `foundry.toml`. Without this setting, some variables may be used without proper permission checks, which will cause failures on production chains. - Use abstract CoFheTest contract to automatically deploy all necessary FHE contracts for testing. CoFheTest also exposes useful test methods such as From b0b5d35fbe9019007a04350f7cc423fbda4ba067 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 14:24:16 +0200 Subject: [PATCH 11/24] tmp: testBed annotations --- packages/mock-contracts/contracts/TestBed.sol | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/mock-contracts/contracts/TestBed.sol b/packages/mock-contracts/contracts/TestBed.sol index 92365d3e..bcf24c22 100644 --- a/packages/mock-contracts/contracts/TestBed.sol +++ b/packages/mock-contracts/contracts/TestBed.sol @@ -3,14 +3,30 @@ pragma solidity ^0.8.13; import '@fhenixprotocol/cofhe-contracts/FHE.sol'; +/// @title TestBed +/// @notice Minimal contract used to smoke-test CoFHE/FHE flows (mocks + permissions + decrypt plumbing). +/// @dev This contract is intentionally simple and is primarily a convenience for Hardhat-based local +/// development: the Hardhat plugin can deploy it automatically when `deployTestBed` is enabled. +/// +/// In Foundry flows, nothing deploys or depends on this contract automatically — you may still +/// deploy/use it in `forge test` if you want a known-good reference target. +/// +/// Important concepts: +/// - `eNumber` is an on-chain encrypted handle type (`euint32`). In real CoFHE, this represents a ciphertext. +/// - `numberHash` stores the unwrapped handle (`ctHash`) as a uint256 for easy inspection/assertions. +/// - After every state update we call `FHE.allowThis(...)` and `FHE.allowSender(...)` so the contract +/// and the transaction sender can continue operating on / decrypting the updated handle. contract TestBed { euint32 public eNumber; uint256 public numberHash; + /// @notice Marker used by deploy scripts/tests to confirm the contract is deployed. function exists() public pure returns (bool) { return true; } + /// @notice Sets `eNumber` from an encrypted input struct. + /// @dev Typically used when testing client-side encryption flows. function setNumber(InEuint32 memory inNumber) public { eNumber = FHE.asEuint32(inNumber); numberHash = uint256(euint32.unwrap(eNumber)); @@ -18,6 +34,8 @@ contract TestBed { FHE.allowSender(eNumber); } + /// @notice Convenience setter that casts a plaintext value into an encrypted handle. + /// @dev Useful for quick smoke tests that don't need pre-encryption. function setNumberTrivial(uint256 inNumber) public { eNumber = FHE.asEuint32(inNumber); numberHash = uint256(euint32.unwrap(eNumber)); @@ -25,12 +43,14 @@ contract TestBed { FHE.allowSender(eNumber); } + /// @notice Increments `eNumber` by 1 using FHE arithmetic. function increment() public { eNumber = FHE.add(eNumber, FHE.asEuint32(1)); FHE.allowThis(eNumber); FHE.allowSender(eNumber); } + /// @notice Adds an encrypted input to `eNumber`. function add(InEuint32 memory inNumber) public { eNumber = FHE.add(eNumber, FHE.asEuint32(inNumber)); @@ -38,6 +58,7 @@ contract TestBed { FHE.allowSender(eNumber); } + /// @notice Subtracts an encrypted input from `eNumber`, clamped to 0 to avoid underflow. function sub(InEuint32 memory inNumber) public { euint32 inAsEuint32 = FHE.asEuint32(inNumber); euint32 eSubOrZero = FHE.select(FHE.lte(inAsEuint32, eNumber), inAsEuint32, FHE.asEuint32(0)); @@ -46,20 +67,25 @@ contract TestBed { FHE.allowSender(eNumber); } + /// @notice Multiplies `eNumber` by an encrypted input. function mul(InEuint32 memory inNumber) public { eNumber = FHE.mul(eNumber, FHE.asEuint32(inNumber)); FHE.allowThis(eNumber); FHE.allowSender(eNumber); } + /// @notice Requests decryption of `eNumber`. + /// @dev In real CoFHE this is asynchronous; in mocks it is simulated. function decrypt() public { FHE.decrypt(eNumber); } + /// @notice Reads a decryption result (reverts if not ready depending on implementation). function getDecryptResult(euint32 input1) public view returns (uint32) { return FHE.getDecryptResult(input1); } + /// @notice Reads a decryption result safely, returning a readiness flag. function getDecryptResultSafe(euint32 input1) public view returns (uint32 value, bool decrypted) { return FHE.getDecryptResultSafe(input1); } From baecc824f4fecae707bdebcfd586751bb716515d Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 14:28:26 +0200 Subject: [PATCH 12/24] tmp: annotations for TestBed.sol and TestBed.t.sol --- packages/mock-contracts/contracts/TestBed.sol | 5 +++-- packages/mock-contracts/test/TestBed.t.sol | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/mock-contracts/contracts/TestBed.sol b/packages/mock-contracts/contracts/TestBed.sol index bcf24c22..51d9819f 100644 --- a/packages/mock-contracts/contracts/TestBed.sol +++ b/packages/mock-contracts/contracts/TestBed.sol @@ -8,8 +8,9 @@ import '@fhenixprotocol/cofhe-contracts/FHE.sol'; /// @dev This contract is intentionally simple and is primarily a convenience for Hardhat-based local /// development: the Hardhat plugin can deploy it automatically when `deployTestBed` is enabled. /// -/// In Foundry flows, nothing deploys or depends on this contract automatically — you may still -/// deploy/use it in `forge test` if you want a known-good reference target. +/// In Foundry flows, nothing deploys or depends on this contract automatically — tests must +/// instantiate it explicitly (this repository includes such Foundry tests). You may deploy/use it +/// in `forge test` if you want a known-good reference target. /// /// Important concepts: /// - `eNumber` is an on-chain encrypted handle type (`euint32`). In real CoFHE, this represents a ciphertext. diff --git a/packages/mock-contracts/test/TestBed.t.sol b/packages/mock-contracts/test/TestBed.t.sol index b4a849a6..628de4f0 100644 --- a/packages/mock-contracts/test/TestBed.t.sol +++ b/packages/mock-contracts/test/TestBed.t.sol @@ -6,11 +6,18 @@ import { TestBed } from '../contracts/TestBed.sol'; import { CoFheTest } from '../contracts/foundry/CoFheTest.sol'; import { FHE, InEuint32, euint8, euint128 } from '@fhenixprotocol/cofhe-contracts/FHE.sol'; +/// @title TestBed Foundry Tests +/// @notice Foundry-native smoke tests for the CoFHE mock environment and FHE Solidity surface. +/// @dev This repo deploys `TestBed` inside Foundry tests as a known-good reference contract. +/// Downstream Foundry users are not required to use `TestBed`; they can deploy/test their own +/// contracts while inheriting from `CoFheTest` to get helper methods like `createInEuint32(...)` +/// and `assertHashValue(...)`. contract TestBedTest is Test, CoFheTest { TestBed private testbed; address private user = makeAddr('user'); + /// @notice Deploys a fresh TestBed instance for each test. function setUp() public { // optional ... enable verbose logging from fhe mocks // setLog(true); @@ -18,6 +25,7 @@ contract TestBedTest is Test, CoFheTest { testbed = new TestBed(); } + /// @notice Fuzz test: create an encrypted input and set it as state. function testSetNumberFuzz(uint32 n) public { InEuint32 memory number = createInEuint32(n, user); @@ -29,6 +37,7 @@ contract TestBedTest is Test, CoFheTest { assertHashValue(testbed.eNumber(), n); } + /// @notice Validates that mock arithmetic matches EVM uint8 wraparound behavior. function testOverflow() public { euint8 a = FHE.asEuint8(240); euint8 b = FHE.asEuint8(240); @@ -37,6 +46,7 @@ contract TestBedTest is Test, CoFheTest { assertHashValue(uint256(euint8.unwrap(c)), (240 + 240) % 256); } + /// @notice Validates division by zero behavior in the mock implementation. function testDivideByZero() public { euint8 a = FHE.asEuint8(240); euint8 b = FHE.asEuint8(0); @@ -45,6 +55,7 @@ contract TestBedTest is Test, CoFheTest { assertHashValue(uint256(euint8.unwrap(c)), type(uint8).max); } + /// @notice Validates 128-bit addition semantics used by the mock implementation. function test128BitsNoOverflow() public { euint128 a = FHE.asEuint128(type(uint128).max); euint128 b = FHE.asEuint128(type(uint128).max); From 6b037970e67e9eb79560c3c9bc3e101a78190688 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 15:01:35 +0200 Subject: [PATCH 13/24] chore: MockQueryDecrypter -> MockThresholdNetwork --- .../test/deploy-mocks.test.ts | 6 +-- packages/hardhat-plugin/README.md | 2 +- packages/hardhat-plugin/src/deploy.ts | 24 ++++----- packages/hardhat-plugin/src/index.ts | 10 ++-- packages/mock-contracts/README.md | 4 +- ...Decrypter.sol => MockThresholdNetwork.sol} | 5 +- .../contracts/foundry/CoFheTest.sol | 18 +++---- .../mock-contracts/scripts/build-artifacts.ts | 2 +- ...ryDecrypter.ts => MockThresholdNetwork.ts} | 6 +-- packages/mock-contracts/src/TestBed.ts | 2 +- packages/mock-contracts/src/index.ts | 2 +- ...ypterAbi.ts => MockThresholdNetworkAbi.ts} | 53 +++++++++++-------- .../sdk/core/decrypt/cofheMocksSealOutput.ts | 4 +- 13 files changed, 76 insertions(+), 62 deletions(-) rename packages/mock-contracts/contracts/{MockQueryDecrypter.sol => MockThresholdNetwork.sol} (95%) rename packages/mock-contracts/src/{MockQueryDecrypter.ts => MockThresholdNetwork.ts} (98%) rename packages/sdk/core/decrypt/{MockQueryDecrypterAbi.ts => MockThresholdNetworkAbi.ts} (80%) diff --git a/packages/hardhat-plugin-test/test/deploy-mocks.test.ts b/packages/hardhat-plugin-test/test/deploy-mocks.test.ts index d349132f..2f4959a3 100644 --- a/packages/hardhat-plugin-test/test/deploy-mocks.test.ts +++ b/packages/hardhat-plugin-test/test/deploy-mocks.test.ts @@ -37,9 +37,9 @@ describe('Deploy Mocks Task', () => { // QUERY DECRYPTER - const queryDecrypterFromCofhesdk = await hre.cofhe.mocks.getMockQueryDecrypter(); - expect(await queryDecrypterFromCofhesdk.exists()).to.be.true; - expect(await queryDecrypterFromCofhesdk.getAddress()).to.be.equal(MOCKS_QUERY_DECRYPTER_ADDRESS); + const thresholdNetworkFromCofhesdk = await hre.cofhe.mocks.getMockThresholdNetwork(); + expect(await thresholdNetworkFromCofhesdk.exists()).to.be.true; + expect(await thresholdNetworkFromCofhesdk.getAddress()).to.be.equal(MOCKS_QUERY_DECRYPTER_ADDRESS); // TEST BED diff --git a/packages/hardhat-plugin/README.md b/packages/hardhat-plugin/README.md index 13486026..a79b46b7 100644 --- a/packages/hardhat-plugin/README.md +++ b/packages/hardhat-plugin/README.md @@ -46,7 +46,7 @@ This plugin uses [cofhe-mock-contracts](https://github.com/FhenixProtocol/cofhe- The mock contracts include: - MockTaskManager: Manages FHE operations and stores plaintext values -- MockQueryDecrypter: Handles decryption requests +- MockThresholdNetwork: Handles decryption requests - MockZkVerifier: Simulates verification of encrypted inputs - ACL: Handles access control diff --git a/packages/hardhat-plugin/src/deploy.ts b/packages/hardhat-plugin/src/deploy.ts index 26dc8cfd..5a424ebc 100644 --- a/packages/hardhat-plugin/src/deploy.ts +++ b/packages/hardhat-plugin/src/deploy.ts @@ -6,7 +6,7 @@ import { MockTaskManagerArtifact, MockACLArtifact, MockZkVerifierArtifact, - MockQueryDecrypterArtifact, + MockThresholdNetworkArtifact, TestBedArtifact, } from '@cofhe/mock-contracts'; @@ -62,8 +62,8 @@ export const deployMocks = async ( const zkVerifier = await deployMockZkVerifier(hre); logDeployment('MockZkVerifier', await zkVerifier.getAddress()); - const queryDecrypter = await deployMockQueryDecrypter(hre, acl); - logDeployment('MockQueryDecrypter', await queryDecrypter.getAddress()); + const thresholdNetwork = await deployMockThresholdNetwork(hre, acl); + logDeployment('MockThresholdNetwork', await thresholdNetwork.getAddress()); if (options.deployTestBed) { logSuccess('TestBed deployment enabled', 2); @@ -154,20 +154,20 @@ const deployMockZkVerifier = async (hre: HardhatRuntimeEnvironment) => { return zkVerifier; }; -const deployMockQueryDecrypter = async (hre: HardhatRuntimeEnvironment, acl: Contract) => { - const queryDecrypter = await deployMockContractFromArtifact(hre, MockQueryDecrypterArtifact); +const deployMockThresholdNetwork = async (hre: HardhatRuntimeEnvironment, acl: Contract) => { + const thresholdNetwork = await deployMockContractFromArtifact(hre, MockThresholdNetworkArtifact); - // Initialize MockQueryDecrypter - const initTx = await queryDecrypter.initialize(TASK_MANAGER_ADDRESS, await acl.getAddress()); + // Initialize MockThresholdNetwork + const initTx = await thresholdNetwork.initialize(TASK_MANAGER_ADDRESS, await acl.getAddress()); await initTx.wait(); - // Check if MockQueryDecrypter exists - const queryDecrypterExists = await queryDecrypter.exists(); - if (!queryDecrypterExists) { - throw new Error('MockQueryDecrypter does not exist'); + // Check if MockThresholdNetwork exists + const exists = await thresholdNetwork.exists(); + if (!exists) { + throw new Error('MockThresholdNetwork does not exist'); } - return queryDecrypter; + return thresholdNetwork; }; const deployTestBedContract = async (hre: HardhatRuntimeEnvironment) => { diff --git a/packages/hardhat-plugin/src/index.ts b/packages/hardhat-plugin/src/index.ts index 5e2a26f3..ae0e5d7c 100644 --- a/packages/hardhat-plugin/src/index.ts +++ b/packages/hardhat-plugin/src/index.ts @@ -24,7 +24,7 @@ import type { Contract } from 'ethers'; import { hardhat } from '@cofhe/sdk/chains'; import { MockACLArtifact, - MockQueryDecrypterArtifact, + MockThresholdNetworkArtifact, MockTaskManagerArtifact, MockZkVerifierArtifact, TestBedArtifact, @@ -313,10 +313,10 @@ declare module 'hardhat/types/runtime' { getMockACL: () => Promise; /** - * Get the MockQueryDecrypter contract - * @returns {Promise} The MockQueryDecrypter contract + * Get the MockThresholdNetwork contract + * @returns {Promise} The MockThresholdNetwork contract */ - getMockQueryDecrypter: () => Promise; + getMockThresholdNetwork: () => Promise; /** * Get the MockZkVerifier contract @@ -417,7 +417,7 @@ extendEnvironment((hre) => { const aclAddress = await taskManager.acl(); return hre.ethers.getContractAt(MockACLArtifact.abi, aclAddress); }, - getMockQueryDecrypter: async () => getFixedMockContract(hre, MockQueryDecrypterArtifact), + getMockThresholdNetwork: async () => getFixedMockContract(hre, MockThresholdNetworkArtifact), getMockZkVerifier: async () => getFixedMockContract(hre, MockZkVerifierArtifact), getTestBed: async () => getFixedMockContract(hre, TestBedArtifact), }, diff --git a/packages/mock-contracts/README.md b/packages/mock-contracts/README.md index 2d96dde5..914743bf 100644 --- a/packages/mock-contracts/README.md +++ b/packages/mock-contracts/README.md @@ -11,7 +11,7 @@ A mock smart contract library for testing CoFHE (Confidential Computing Framewor - Mock implementations of core CoFHE contracts: - MockTaskManager - - MockQueryDecrypter + - MockThresholdNetwork - MockZkVerifier - ACL (Access Control List) - Synchronous operation simulation with mock delays @@ -136,7 +136,7 @@ Off-chain decryption is performed by calling the `cofheClient.decryptHandle` fun When interacting with CoFHE this request is routed to the Threshold Network, which will perform the decryption operation, ultimately returning a decrypted result. -When working with the mocks, the `cofheClient` will instead query the `MockQueryDecrypter` contract, which will verify the request `permit`, and return the decrypted result. +When working with the mocks, the `cofheClient` will instead query the `MockThresholdNetwork` contract, which will verify the request `permit`, and return the decrypted result. ### Using Foundry diff --git a/packages/mock-contracts/contracts/MockQueryDecrypter.sol b/packages/mock-contracts/contracts/MockThresholdNetwork.sol similarity index 95% rename from packages/mock-contracts/contracts/MockQueryDecrypter.sol rename to packages/mock-contracts/contracts/MockThresholdNetwork.sol index eaa43e39..e55efeac 100644 --- a/packages/mock-contracts/contracts/MockQueryDecrypter.sol +++ b/packages/mock-contracts/contracts/MockThresholdNetwork.sol @@ -1,13 +1,16 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear // solhint-disable one-contract-per-file +// NOTE: This file was renamed from `MockQueryDecrypter.sol` to better reflect that it mocks +// threshold-network-style decryption/sealing behavior in local/testing environments. + pragma solidity >=0.8.19 <0.9.0; import { MockACL } from './MockACL.sol'; import { MockTaskManager } from './MockTaskManager.sol'; import { Permission, MockPermissioned } from './Permissioned.sol'; -contract MockQueryDecrypter { +contract MockThresholdNetwork { MockTaskManager public mockTaskManager; MockACL public mockAcl; diff --git a/packages/mock-contracts/contracts/foundry/CoFheTest.sol b/packages/mock-contracts/contracts/foundry/CoFheTest.sol index 0045a202..1b3293a1 100644 --- a/packages/mock-contracts/contracts/foundry/CoFheTest.sol +++ b/packages/mock-contracts/contracts/foundry/CoFheTest.sol @@ -9,7 +9,7 @@ import { MockZkVerifier } from '../MockZkVerifier.sol'; import { MockZkVerifierSigner } from './MockZkVerifierSigner.sol'; import { MessageHashUtils } from '@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol'; import { Permission, PermissionUtils } from '../Permissioned.sol'; -import { MockQueryDecrypter } from '../MockQueryDecrypter.sol'; +import { MockThresholdNetwork } from '../MockThresholdNetwork.sol'; import { SIGNER_ADDRESS } from '../MockCoFHE.sol'; abstract contract CoFheTest is Test { @@ -17,7 +17,7 @@ abstract contract CoFheTest is Test { MockZkVerifier public mockZkVerifier; MockZkVerifierSigner public mockZkVerifierSigner; MockACL public mockAcl; - MockQueryDecrypter public mockQueryDecrypter; + MockThresholdNetwork public mockThresholdNetwork; // Keep these in sync with `packages/sdk/core/consts.ts` address constant ZK_VERIFIER_ADDRESS = 0x0000000000000000000000000000000000005001; @@ -79,10 +79,10 @@ abstract contract CoFheTest is Test { // QUERY DECRYPTER - deployCodeTo('MockQueryDecrypter.sol:MockQueryDecrypter', QUERY_DECRYPTER_ADDRESS); - mockQueryDecrypter = MockQueryDecrypter(QUERY_DECRYPTER_ADDRESS); - vm.label(address(mockQueryDecrypter), 'MockQueryDecrypter'); - mockQueryDecrypter.initialize(TASK_MANAGER_ADDRESS, address(mockAcl)); + deployCodeTo('MockThresholdNetwork.sol:MockThresholdNetwork', QUERY_DECRYPTER_ADDRESS); + mockThresholdNetwork = MockThresholdNetwork(QUERY_DECRYPTER_ADDRESS); + vm.label(address(mockThresholdNetwork), 'MockThresholdNetwork'); + mockThresholdNetwork.initialize(TASK_MANAGER_ADDRESS, address(mockAcl)); // SET LOG OPS @@ -416,7 +416,7 @@ abstract contract CoFheTest is Test { uint256 hostChainId, Permission memory permission ) public view returns (bool, string memory error, uint256) { - return mockQueryDecrypter.queryDecrypt(ctHash, hostChainId, permission); + return mockThresholdNetwork.queryDecrypt(ctHash, hostChainId, permission); } function querySealOutput( @@ -424,10 +424,10 @@ abstract contract CoFheTest is Test { uint256 hostChainId, Permission memory permission ) public view returns (bool, string memory error, bytes32) { - return mockQueryDecrypter.querySealOutput(ctHash, hostChainId, permission); + return mockThresholdNetwork.querySealOutput(ctHash, hostChainId, permission); } function unseal(bytes32 hashed, bytes32 key) public view returns (uint256) { - return mockQueryDecrypter.unseal(hashed, key); + return mockThresholdNetwork.unseal(hashed, key); } } diff --git a/packages/mock-contracts/scripts/build-artifacts.ts b/packages/mock-contracts/scripts/build-artifacts.ts index b689d2bd..38cea8bb 100644 --- a/packages/mock-contracts/scripts/build-artifacts.ts +++ b/packages/mock-contracts/scripts/build-artifacts.ts @@ -10,7 +10,7 @@ import { const fixedContracts = { MockTaskManager: TASK_MANAGER_ADDRESS, MockZkVerifier: MOCKS_ZK_VERIFIER_ADDRESS, - MockQueryDecrypter: MOCKS_QUERY_DECRYPTER_ADDRESS, + MockThresholdNetwork: MOCKS_QUERY_DECRYPTER_ADDRESS, TestBed: TEST_BED_ADDRESS, }; diff --git a/packages/mock-contracts/src/MockQueryDecrypter.ts b/packages/mock-contracts/src/MockThresholdNetwork.ts similarity index 98% rename from packages/mock-contracts/src/MockQueryDecrypter.ts rename to packages/mock-contracts/src/MockThresholdNetwork.ts index db1ef416..0a74e087 100644 --- a/packages/mock-contracts/src/MockQueryDecrypter.ts +++ b/packages/mock-contracts/src/MockThresholdNetwork.ts @@ -1,8 +1,8 @@ // This file is auto-generated by build-artifacts.ts import { type MockArtifact } from './types'; -export const MockQueryDecrypterArtifact = { - contractName: 'MockQueryDecrypter', +export const MockThresholdNetworkArtifact = { + contractName: 'MockThresholdNetwork', isFixed: true, fixedAddress: '0x0000000000000000000000000000000000005002', abi: [ @@ -348,5 +348,5 @@ export const MockQueryDecrypterArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b506004361061009c575f3560e01c80637e0f4b5b116100645780637e0f4b5b1461015a5780638a5c8c7f14610178578063a02eb534146101a8578063a0639f54146101da578063ff6957d31461020c5761009c565b806309ba3156146100a05780631a1992a9146100d2578063267c4ae414610102578063485cc955146101205780634cdc014d1461013c575b5f5ffd5b6100ba60048036038101906100b591906110b5565b61023c565b6040516100c9939291906111aa565b60405180910390f35b6100ec60048036038101906100e791906111e6565b61051f565b6040516100f99190611224565b60405180910390f35b61010a61052d565b604051610117919061123d565b60405180910390f35b61013a60048036038101906101359190611256565b610535565b005b6101446105b8565b60405161015191906112ef565b60405180910390f35b6101626105dd565b60405161016f9190611328565b60405180910390f35b610192600480360381019061018d9190611341565b610601565b60405161019f919061138e565b60405180910390f35b6101c260048036038101906101bd91906113a7565b61060f565b6040516101d1939291906113f7565b60405180910390f35b6101f460048036038101906101ef91906110b5565b61089e565b604051610203939291906113f7565b60405180910390f35b61022660048036038101906102219190611433565b610b28565b604051610233919061147a565b60405180910390f35b5f60605f5f5f1b8460a001510361027f576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016102dc9291906115dc565b602060405180830381865afa92505050801561031657506040513d601f19601f820116820180604052508101906103139190611634565b60015b6104025761032261166b565b806308c379a003610353575061033661168a565b8061034157506103b8565b5f815f5f1b9450945094505050610516565b634e487b71036103b857610365611719565b9061037057506103b8565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610516565b3d805f81146103e2576040519150601f19603f3d011682016040523d82523d5f602084013e6103e7565b606091505b505f6103f282610b28565b5f5f1b9450945094505050610516565b8091505080610452575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610516565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104ac919061138e565b602060405180830381865afa1580156104c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104eb919061174b565b905060016104fd828860a0015161051f565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b8152600401610670929190611785565b602060405180830381865afa9250505080156106aa57506040513d601f19601f820116820180604052508101906106a79190611634565b60015b610790576106b661166b565b806308c379a0036106e557506106ca61168a565b806106d55750610748565b5f815f9450945094505050610895565b634e487b7103610748576106f7611719565b906107025750610748565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610895565b3d805f8114610772576040519150601f19603f3d011682016040523d82523d5f602084013e610777565b606091505b505f61078282610b28565b5f9450945094505050610895565b80915050806107de575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610895565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610838919061138e565b602060405180830381865afa158015610853573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610877919061174b565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016108ff9291906115dc565b602060405180830381865afa92505050801561093957506040513d601f19601f820116820180604052508101906109369190611634565b60015b610a1f5761094561166b565b806308c379a003610974575061095961168a565b8061096457506109d7565b5f815f9450945094505050610b1f565b634e487b71036109d757610986611719565b9061099157506109d7565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b1f565b3d805f8114610a01576040519150601f19603f3d011682016040523d82523d5f602084013e610a06565b606091505b505f610a1182610b28565b5f9450945094505050610b1f565b8091505080610a6d575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b1f565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610ac8919061138e565b602060405180830381865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b07919061174b565b60405180602001604052805f81525090935093509350505b93509350939050565b60605f82610b3590611806565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bc1576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f4578706972656400000000000000815250915050610d5f565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c2e5760405180606001604052806021815260200161189160219139915050610d5f565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c9b5760405180606001604052806024815260200161186d60249139915050610d5f565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d25576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c6564000000000000815250915050610d5f565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610d8781610d75565b8114610d91575f5ffd5b50565b5f81359050610da281610d7e565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610df282610dac565b810181811067ffffffffffffffff82111715610e1157610e10610dbc565b5b80604052505050565b5f610e23610d64565b9050610e2f8282610de9565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6182610e38565b9050919050565b610e7181610e57565b8114610e7b575f5ffd5b50565b5f81359050610e8c81610e68565b92915050565b5f67ffffffffffffffff82169050919050565b610eae81610e92565b8114610eb8575f5ffd5b50565b5f81359050610ec981610ea5565b92915050565b5f819050919050565b610ee181610ecf565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115610f2457610f23610dbc565b5b610f2d82610dac565b9050602081019050919050565b828183375f83830152505050565b5f610f5a610f5584610f0a565b610e1a565b905082815260208101848484011115610f7657610f75610f06565b5b610f81848285610f3a565b509392505050565b5f82601f830112610f9d57610f9c610f02565b5b8135610fad848260208601610f48565b91505092915050565b5f6101008284031215610fcc57610fcb610da8565b5b610fd7610100610e1a565b90505f610fe684828501610e7e565b5f830152506020610ff984828501610ebb565b602083015250604061100d84828501610e7e565b604083015250606061102184828501610d94565b606083015250608061103584828501610e7e565b60808301525060a061104984828501610eee565b60a08301525060c082013567ffffffffffffffff81111561106d5761106c610e34565b5b61107984828501610f89565b60c08301525060e082013567ffffffffffffffff81111561109d5761109c610e34565b5b6110a984828501610f89565b60e08301525092915050565b5f5f5f606084860312156110cc576110cb610d6d565b5b5f6110d986828701610d94565b93505060206110ea86828701610d94565b925050604084013567ffffffffffffffff81111561110b5761110a610d71565b5b61111786828701610fb6565b9150509250925092565b5f8115159050919050565b61113581611121565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61116d8261113b565b6111778185611145565b9350611187818560208601611155565b61119081610dac565b840191505092915050565b6111a481610ecf565b82525050565b5f6060820190506111bd5f83018661112c565b81810360208301526111cf8185611163565b90506111de604083018461119b565b949350505050565b5f5f604083850312156111fc576111fb610d6d565b5b5f61120985828601610d94565b925050602061121a85828601610eee565b9150509250929050565b5f6020820190506112375f83018461119b565b92915050565b5f6020820190506112505f83018461112c565b92915050565b5f5f6040838503121561126c5761126b610d6d565b5b5f61127985828601610e7e565b925050602061128a85828601610e7e565b9150509250929050565b5f819050919050565b5f6112b76112b26112ad84610e38565b611294565b610e38565b9050919050565b5f6112c88261129d565b9050919050565b5f6112d9826112be565b9050919050565b6112e9816112cf565b82525050565b5f6020820190506113025f8301846112e0565b92915050565b5f611312826112be565b9050919050565b61132281611308565b82525050565b5f60208201905061133b5f830184611319565b92915050565b5f5f6040838503121561135757611356610d6d565b5b5f61136485828601610eee565b925050602061137585828601610eee565b9150509250929050565b61138881610d75565b82525050565b5f6020820190506113a15f83018461137f565b92915050565b5f5f5f606084860312156113be576113bd610d6d565b5b5f6113cb86828701610d94565b93505060206113dc86828701610d94565b92505060406113ed86828701610e7e565b9150509250925092565b5f60608201905061140a5f83018661112c565b818103602083015261141c8185611163565b905061142b604083018461137f565b949350505050565b5f6020828403121561144857611447610d6d565b5b5f82013567ffffffffffffffff81111561146557611464610d71565b5b61147184828501610f89565b91505092915050565b5f6020820190508181035f8301526114928184611163565b905092915050565b6114a381610e57565b82525050565b6114b281610e92565b82525050565b6114c181610d75565b82525050565b6114d081610ecf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6114fa826114d6565b61150481856114e0565b9350611514818560208601611155565b61151d81610dac565b840191505092915050565b5f61010083015f83015161153e5f86018261149a565b50602083015161155160208601826114a9565b506040830151611564604086018261149a565b50606083015161157760608601826114b8565b50608083015161158a608086018261149a565b5060a083015161159d60a08601826114c7565b5060c083015184820360c08601526115b582826114f0565b91505060e083015184820360e08601526115cf82826114f0565b9150508091505092915050565b5f6040820190508181035f8301526115f48185611528565b9050611603602083018461137f565b9392505050565b61161381611121565b811461161d575f5ffd5b50565b5f8151905061162e8161160a565b92915050565b5f6020828403121561164957611648610d6d565b5b5f61165684828501611620565b91505092915050565b5f8160e01c9050919050565b5f60033d11156116875760045f5f3e6116845f5161165f565b90505b90565b5f60443d106117165761169b610d64565b60043d036004823e80513d602482011167ffffffffffffffff821117156116c3575050611716565b808201805167ffffffffffffffff8111156116e15750505050611716565b80602083010160043d0385018111156116fe575050505050611716565b61170d82602001850186610de9565b82955050505050505b90565b5f5f60233d111561173357602060045f3e600191505f5190505b9091565b5f8151905061174581610d7e565b92915050565b5f602082840312156117605761175f610d6d565b5b5f61176d84828501611737565b91505092915050565b61177f81610e57565b82525050565b5f6040820190506117985f83018561137f565b6117a56020830184611776565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f6117f182516117bb565b80915050919050565b5f82821b905092915050565b5f611810826114d6565b8261181a846117ac565b9050611825816117e6565b92506004821015611865576118607fffffffff00000000000000000000000000000000000000000000000000000000836004036008026117fa565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220fd8e9a6aa7147960d4cd0eebd7d8331bb5cbbe3b6c8809265fe5db60d8f91d3b64736f6c634300081c0033', + '0x608060405234801561000f575f5ffd5b506004361061009c575f3560e01c80637e0f4b5b116100645780637e0f4b5b1461015a5780638a5c8c7f14610178578063a02eb534146101a8578063a0639f54146101da578063ff6957d31461020c5761009c565b806309ba3156146100a05780631a1992a9146100d2578063267c4ae414610102578063485cc955146101205780634cdc014d1461013c575b5f5ffd5b6100ba60048036038101906100b591906110b5565b61023c565b6040516100c9939291906111aa565b60405180910390f35b6100ec60048036038101906100e791906111e6565b61051f565b6040516100f99190611224565b60405180910390f35b61010a61052d565b604051610117919061123d565b60405180910390f35b61013a60048036038101906101359190611256565b610535565b005b6101446105b8565b60405161015191906112ef565b60405180910390f35b6101626105dd565b60405161016f9190611328565b60405180910390f35b610192600480360381019061018d9190611341565b610601565b60405161019f919061138e565b60405180910390f35b6101c260048036038101906101bd91906113a7565b61060f565b6040516101d1939291906113f7565b60405180910390f35b6101f460048036038101906101ef91906110b5565b61089e565b604051610203939291906113f7565b60405180910390f35b61022660048036038101906102219190611433565b610b28565b604051610233919061147a565b60405180910390f35b5f60605f5f5f1b8460a001510361027f576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016102dc9291906115dc565b602060405180830381865afa92505050801561031657506040513d601f19601f820116820180604052508101906103139190611634565b60015b6104025761032261166b565b806308c379a003610353575061033661168a565b8061034157506103b8565b5f815f5f1b9450945094505050610516565b634e487b71036103b857610365611719565b9061037057506103b8565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610516565b3d805f81146103e2576040519150601f19603f3d011682016040523d82523d5f602084013e6103e7565b606091505b505f6103f282610b28565b5f5f1b9450945094505050610516565b8091505080610452575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610516565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104ac919061138e565b602060405180830381865afa1580156104c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104eb919061174b565b905060016104fd828860a0015161051f565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b8152600401610670929190611785565b602060405180830381865afa9250505080156106aa57506040513d601f19601f820116820180604052508101906106a79190611634565b60015b610790576106b661166b565b806308c379a0036106e557506106ca61168a565b806106d55750610748565b5f815f9450945094505050610895565b634e487b7103610748576106f7611719565b906107025750610748565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610895565b3d805f8114610772576040519150601f19603f3d011682016040523d82523d5f602084013e610777565b606091505b505f61078282610b28565b5f9450945094505050610895565b80915050806107de575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610895565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610838919061138e565b602060405180830381865afa158015610853573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610877919061174b565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016108ff9291906115dc565b602060405180830381865afa92505050801561093957506040513d601f19601f820116820180604052508101906109369190611634565b60015b610a1f5761094561166b565b806308c379a003610974575061095961168a565b8061096457506109d7565b5f815f9450945094505050610b1f565b634e487b71036109d757610986611719565b9061099157506109d7565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b1f565b3d805f8114610a01576040519150601f19603f3d011682016040523d82523d5f602084013e610a06565b606091505b505f610a1182610b28565b5f9450945094505050610b1f565b8091505080610a6d575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b1f565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610ac8919061138e565b602060405180830381865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b07919061174b565b60405180602001604052805f81525090935093509350505b93509350939050565b60605f82610b3590611806565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bc1576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f4578706972656400000000000000815250915050610d5f565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c2e5760405180606001604052806021815260200161189160219139915050610d5f565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c9b5760405180606001604052806024815260200161186d60249139915050610d5f565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d25576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c6564000000000000815250915050610d5f565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610d8781610d75565b8114610d91575f5ffd5b50565b5f81359050610da281610d7e565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610df282610dac565b810181811067ffffffffffffffff82111715610e1157610e10610dbc565b5b80604052505050565b5f610e23610d64565b9050610e2f8282610de9565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6182610e38565b9050919050565b610e7181610e57565b8114610e7b575f5ffd5b50565b5f81359050610e8c81610e68565b92915050565b5f67ffffffffffffffff82169050919050565b610eae81610e92565b8114610eb8575f5ffd5b50565b5f81359050610ec981610ea5565b92915050565b5f819050919050565b610ee181610ecf565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115610f2457610f23610dbc565b5b610f2d82610dac565b9050602081019050919050565b828183375f83830152505050565b5f610f5a610f5584610f0a565b610e1a565b905082815260208101848484011115610f7657610f75610f06565b5b610f81848285610f3a565b509392505050565b5f82601f830112610f9d57610f9c610f02565b5b8135610fad848260208601610f48565b91505092915050565b5f6101008284031215610fcc57610fcb610da8565b5b610fd7610100610e1a565b90505f610fe684828501610e7e565b5f830152506020610ff984828501610ebb565b602083015250604061100d84828501610e7e565b604083015250606061102184828501610d94565b606083015250608061103584828501610e7e565b60808301525060a061104984828501610eee565b60a08301525060c082013567ffffffffffffffff81111561106d5761106c610e34565b5b61107984828501610f89565b60c08301525060e082013567ffffffffffffffff81111561109d5761109c610e34565b5b6110a984828501610f89565b60e08301525092915050565b5f5f5f606084860312156110cc576110cb610d6d565b5b5f6110d986828701610d94565b93505060206110ea86828701610d94565b925050604084013567ffffffffffffffff81111561110b5761110a610d71565b5b61111786828701610fb6565b9150509250925092565b5f8115159050919050565b61113581611121565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61116d8261113b565b6111778185611145565b9350611187818560208601611155565b61119081610dac565b840191505092915050565b6111a481610ecf565b82525050565b5f6060820190506111bd5f83018661112c565b81810360208301526111cf8185611163565b90506111de604083018461119b565b949350505050565b5f5f604083850312156111fc576111fb610d6d565b5b5f61120985828601610d94565b925050602061121a85828601610eee565b9150509250929050565b5f6020820190506112375f83018461119b565b92915050565b5f6020820190506112505f83018461112c565b92915050565b5f5f6040838503121561126c5761126b610d6d565b5b5f61127985828601610e7e565b925050602061128a85828601610e7e565b9150509250929050565b5f819050919050565b5f6112b76112b26112ad84610e38565b611294565b610e38565b9050919050565b5f6112c88261129d565b9050919050565b5f6112d9826112be565b9050919050565b6112e9816112cf565b82525050565b5f6020820190506113025f8301846112e0565b92915050565b5f611312826112be565b9050919050565b61132281611308565b82525050565b5f60208201905061133b5f830184611319565b92915050565b5f5f6040838503121561135757611356610d6d565b5b5f61136485828601610eee565b925050602061137585828601610eee565b9150509250929050565b61138881610d75565b82525050565b5f6020820190506113a15f83018461137f565b92915050565b5f5f5f606084860312156113be576113bd610d6d565b5b5f6113cb86828701610d94565b93505060206113dc86828701610d94565b92505060406113ed86828701610e7e565b9150509250925092565b5f60608201905061140a5f83018661112c565b818103602083015261141c8185611163565b905061142b604083018461137f565b949350505050565b5f6020828403121561144857611447610d6d565b5b5f82013567ffffffffffffffff81111561146557611464610d71565b5b61147184828501610f89565b91505092915050565b5f6020820190508181035f8301526114928184611163565b905092915050565b6114a381610e57565b82525050565b6114b281610e92565b82525050565b6114c181610d75565b82525050565b6114d081610ecf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6114fa826114d6565b61150481856114e0565b9350611514818560208601611155565b61151d81610dac565b840191505092915050565b5f61010083015f83015161153e5f86018261149a565b50602083015161155160208601826114a9565b506040830151611564604086018261149a565b50606083015161157760608601826114b8565b50608083015161158a608086018261149a565b5060a083015161159d60a08601826114c7565b5060c083015184820360c08601526115b582826114f0565b91505060e083015184820360e08601526115cf82826114f0565b9150508091505092915050565b5f6040820190508181035f8301526115f48185611528565b9050611603602083018461137f565b9392505050565b61161381611121565b811461161d575f5ffd5b50565b5f8151905061162e8161160a565b92915050565b5f6020828403121561164957611648610d6d565b5b5f61165684828501611620565b91505092915050565b5f8160e01c9050919050565b5f60033d11156116875760045f5f3e6116845f5161165f565b90505b90565b5f60443d106117165761169b610d64565b60043d036004823e80513d602482011167ffffffffffffffff821117156116c3575050611716565b808201805167ffffffffffffffff8111156116e15750505050611716565b80602083010160043d0385018111156116fe575050505050611716565b61170d82602001850186610de9565b82955050505050505b90565b5f5f60233d111561173357602060045f3e600191505f5190505b9091565b5f8151905061174581610d7e565b92915050565b5f602082840312156117605761175f610d6d565b5b5f61176d84828501611737565b91505092915050565b61177f81610e57565b82525050565b5f6040820190506117985f83018561137f565b6117a56020830184611776565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f6117f182516117bb565b80915050919050565b5f82821b905092915050565b5f611810826114d6565b8261181a846117ac565b9050611825816117e6565b92506004821015611865576118607fffffffff00000000000000000000000000000000000000000000000000000000836004036008026117fa565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220654d6bab26b804b5d941c0140eea91e488571d0925c255a2dd894a9677f0ce9564736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/TestBed.ts b/packages/mock-contracts/src/TestBed.ts index 60cb5ee9..54e87bf1 100644 --- a/packages/mock-contracts/src/TestBed.ts +++ b/packages/mock-contracts/src/TestBed.ts @@ -284,5 +284,5 @@ export const TestBedArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b50600436106100b2575f3560e01c806367c651741161006f57806367c651741461017957806384f091db1461019757806384ff25c6146101b3578063b5872e8c146101cf578063d09de08a146101eb578063d7a0faa2146101f5576100b2565b80631292f65a146100b657806319d8a05b146100e6578063260ec88914610104578063267c4ae4146101355780633983d43014610153578063647096091461015d575b5f5ffd5b6100d060048036038101906100cb9190610fd4565b610211565b6040516100dd919061101d565b60405180910390f35b6100ee610222565b6040516100fb9190611056565b60405180910390f35b61011e60048036038101906101199190610fd4565b610227565b60405161012c929190611089565b60405180910390f35b61013d61023b565b60405161014a91906110b0565b60405180910390f35b61015b610243565b005b61017760048036038101906101729190611307565b61024f565b005b6101816102a4565b60405161018e919061135d565b60405180910390f35b6101b160048036038101906101ac9190611307565b6102aa565b005b6101cd60048036038101906101c89190611307565b6102d9565b005b6101e960048036038101906101e49190611307565b610308565b005b6101f3610337565b005b61020f600480360381019061020a9190611376565b610366565b005b5f61021b82610395565b9050919050565b5f5481565b5f5f610232836103a6565b91509150915091565b5f6001905090565b61024d5f546103c4565b565b5f610259826103ea565b90505f61027961026a835f54610412565b836102745f61045b565b61046d565b90506102865f54826104cf565b5f819055506102955f54610518565b61029f5f54610599565b505050565b60015481565b6102bd5f546102b8836103ea565b61061a565b5f819055506102cc5f54610518565b6102d65f54610599565b50565b6102ec5f546102e7836103ea565b610663565b5f819055506102fb5f54610518565b6103055f54610599565b50565b610311816103ea565b5f819055505f545f1c60018190555061032a5f54610518565b6103345f54610599565b50565b61034b5f54610346600161045b565b610663565b5f8190555061035a5f54610518565b6103645f54610599565b565b61036f8161045b565b5f819055505f545f1c6001819055506103885f54610518565b6103925f54610599565b50565b5f61039f826106ac565b9050919050565b5f5f5f5f6103b385610742565b915091508181935093505050915091565b6103cd816107da565b6103dd576103da5f61045b565b90505b6103e6816107eb565b5050565b5f6103fa82604001516004610872565b61040b610406836108c2565b610904565b9050919050565b5f61041c836107da565b61042c576104295f61045b565b92505b610435826107da565b610445576104425f61045b565b91505b61045360048484601361099d565b905092915050565b5f610466825f610a8e565b9050919050565b5f61047784610aa8565b610487576104845f610ab9565b93505b610490836107da565b6104a05761049d5f61045b565b92505b6104a9826107da565b6104b9576104b65f61045b565b91505b6104c66004858585610acb565b90509392505050565b5f6104d9836107da565b6104e9576104e65f61045b565b92505b6104f2826107da565b610502576104ff5f61045b565b91505b61051060048484600761099d565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c306040518363ffffffff1660e01b81526004016105699291906113e0565b5f604051808303815f87803b158015610580575f5ffd5b505af1158015610592573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c336040518363ffffffff1660e01b81526004016105ea9291906113e0565b5f604051808303815f87803b158015610601575f5ffd5b505af1158015610613573d5f5f3e3d5ffd5b5050505050565b5f610624836107da565b610634576106315f61045b565b92505b61063d826107da565b61064d5761064a5f61045b565b91505b61065b60048484600f61099d565b905092915050565b5f61066d836107da565b61067d5761067a5f61045b565b92505b610686826107da565b610696576106935f61045b565b91505b6106a460048484600861099d565b905092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f835f1c6040518263ffffffff1660e01b81526004016106fc919061135d565b602060405180830381865afa158015610717573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073b919061141b565b9050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9845f1c6040518263ffffffff1660e01b8152600401610793919061135d565b6040805180830381865afa1580156107ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d19190611470565b91509150915091565b5f6107e482610bbe565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166308289827835f1c336040518363ffffffff1660e01b815260040161083d9291906113e0565b5f604051808303815f87803b158015610854575f5ffd5b505af1158015610866573d5f5f3e3d5ffd5b50505050819050919050565b8060ff168260ff16146108be5781816040517f67cf30710000000000000000000000000000000000000000000000000000000081526004016108b59291906114bd565b60405180910390fd5b5050565b6108ca610f65565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016109549291906115c2565b6020604051808303815f875af1158015610970573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610994919061141b565b5f1b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd86846109da8888610bcc565b5f67ffffffffffffffff8111156109f4576109f36110dd565b5b604051908082528060200260200182016040528015610a225781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610a42949392919061170b565b6020604051808303815f875af1158015610a5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a82919061141b565b5f1b9050949350505050565b5f5f610a9c84600485610c6a565b90508091505092915050565b5f610ab282610bbe565b9050919050565b5f610ac4825f610d67565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610b0a888888610d90565b5f67ffffffffffffffff811115610b2457610b236110dd565b5b604051908082528060200260200182016040528015610b525781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610b72949392919061170b565b6020604051808303815f875af1158015610b8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb2919061141b565b5f1b9050949350505050565b5f5f5f1b8214159050919050565b60605f600267ffffffffffffffff811115610bea57610be96110dd565b5b604051908082528060200260200182016040528015610c185781602001602082028036833780820191505090505b509050835f1c815f81518110610c3157610c3061175c565b5b602002602001018181525050825f1c81600181518110610c5457610c5361175c565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610cb857610cb76110dd565b5b604051908082528060200260200182016040528015610ce65781602001602082028036833780820191505090505b50610cfd898960ff16610cf88a610e52565b610ea9565b6040518563ffffffff1660e01b8152600401610d1c949392919061170b565b6020604051808303815f875af1158015610d38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5c919061141b565b5f1b90509392505050565b5f5f5f90508315610d7757600190505b5f610d83825f86610c6a565b9050809250505092915050565b60605f600367ffffffffffffffff811115610dae57610dad6110dd565b5b604051908082528060200260200182016040528015610ddc5781602001602082028036833780820191505090505b509050845f1c815f81518110610df557610df461175c565b5b602002602001018181525050835f1c81600181518110610e1857610e1761175c565b5b602002602001018181525050825f1c81600281518110610e3b57610e3a61175c565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610e9b57816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610e9291906117a4565b60405180910390fd5b8163ffffffff169050919050565b60605f600367ffffffffffffffff811115610ec757610ec66110dd565b5b604051908082528060200260200182016040528015610ef55781602001602082028036833780820191505090505b50905084815f81518110610f0c57610f0b61175c565b5b6020026020010181815250508381600181518110610f2d57610f2c61175c565b5b6020026020010181815250508281600281518110610f4e57610f4d61175c565b5b602002602001018181525050809150509392505050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610fb381610fa1565b8114610fbd575f5ffd5b50565b5f81359050610fce81610faa565b92915050565b5f60208284031215610fe957610fe8610f99565b5b5f610ff684828501610fc0565b91505092915050565b5f63ffffffff82169050919050565b61101781610fff565b82525050565b5f6020820190506110305f83018461100e565b92915050565b5f61104082610fa1565b9050919050565b61105081611036565b82525050565b5f6020820190506110695f830184611047565b92915050565b5f8115159050919050565b6110838161106f565b82525050565b5f60408201905061109c5f83018561100e565b6110a9602083018461107a565b9392505050565b5f6020820190506110c35f83018461107a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611113826110cd565b810181811067ffffffffffffffff82111715611132576111316110dd565b5b80604052505050565b5f611144610f90565b9050611150828261110a565b919050565b5f5ffd5b5f819050919050565b61116b81611159565b8114611175575f5ffd5b50565b5f8135905061118681611162565b92915050565b5f60ff82169050919050565b6111a18161118c565b81146111ab575f5ffd5b50565b5f813590506111bc81611198565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156111e4576111e36110dd565b5b6111ed826110cd565b9050602081019050919050565b828183375f83830152505050565b5f61121a611215846111ca565b61113b565b905082815260208101848484011115611236576112356111c6565b5b6112418482856111fa565b509392505050565b5f82601f83011261125d5761125c6111c2565b5b813561126d848260208601611208565b91505092915050565b5f6080828403121561128b5761128a6110c9565b5b611295608061113b565b90505f6112a484828501611178565b5f8301525060206112b7848285016111ae565b60208301525060406112cb848285016111ae565b604083015250606082013567ffffffffffffffff8111156112ef576112ee611155565b5b6112fb84828501611249565b60608301525092915050565b5f6020828403121561131c5761131b610f99565b5b5f82013567ffffffffffffffff81111561133957611338610f9d565b5b61134584828501611276565b91505092915050565b61135781611159565b82525050565b5f6020820190506113705f83018461134e565b92915050565b5f6020828403121561138b5761138a610f99565b5b5f61139884828501611178565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113ca826113a1565b9050919050565b6113da816113c0565b82525050565b5f6040820190506113f35f83018561134e565b61140060208301846113d1565b9392505050565b5f8151905061141581611162565b92915050565b5f602082840312156114305761142f610f99565b5b5f61143d84828501611407565b91505092915050565b61144f8161106f565b8114611459575f5ffd5b50565b5f8151905061146a81611446565b92915050565b5f5f6040838503121561148657611485610f99565b5b5f61149385828601611407565b92505060206114a48582860161145c565b9150509250929050565b6114b78161118c565b82525050565b5f6040820190506114d05f8301856114ae565b6114dd60208301846114ae565b9392505050565b6114ed81611159565b82525050565b6114fc8161118c565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61153482611502565b61153e818561150c565b935061154e81856020860161151c565b611557816110cd565b840191505092915050565b5f608083015f8301516115775f8601826114e4565b50602083015161158a60208601826114f3565b50604083015161159d60408601826114f3565b50606083015184820360608601526115b5828261152a565b9150508091505092915050565b5f6040820190508181035f8301526115da8185611562565b90506115e960208301846113d1565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020811061162e5761162d6115f0565b5b50565b5f81905061163e8261161d565b919050565b5f61164d82611631565b9050919050565b61165d81611643565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61169783836114e4565b60208301905092915050565b5f602082019050919050565b5f6116b982611663565b6116c3818561166d565b93506116ce8361167d565b805f5b838110156116fe5781516116e5888261168c565b97506116f0836116a3565b9250506001810190506116d1565b5085935050505092915050565b5f60808201905061171e5f8301876114ae565b61172b6020830186611654565b818103604083015261173d81856116af565b9050818103606083015261175181846116af565b905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b61179e81611789565b82525050565b5f6020820190506117b75f830184611795565b9291505056fea264697066735822122073ac55a0782990f2903a9db8268d740b09bc94dd31b938921048980bcec8c1e464736f6c634300081c0033', + '0x608060405234801561000f575f5ffd5b50600436106100b2575f3560e01c806367c651741161006f57806367c651741461017957806384f091db1461019757806384ff25c6146101b3578063b5872e8c146101cf578063d09de08a146101eb578063d7a0faa2146101f5576100b2565b80631292f65a146100b657806319d8a05b146100e6578063260ec88914610104578063267c4ae4146101355780633983d43014610153578063647096091461015d575b5f5ffd5b6100d060048036038101906100cb9190610fd4565b610211565b6040516100dd919061101d565b60405180910390f35b6100ee610222565b6040516100fb9190611056565b60405180910390f35b61011e60048036038101906101199190610fd4565b610227565b60405161012c929190611089565b60405180910390f35b61013d61023b565b60405161014a91906110b0565b60405180910390f35b61015b610243565b005b61017760048036038101906101729190611307565b61024f565b005b6101816102a4565b60405161018e919061135d565b60405180910390f35b6101b160048036038101906101ac9190611307565b6102aa565b005b6101cd60048036038101906101c89190611307565b6102d9565b005b6101e960048036038101906101e49190611307565b610308565b005b6101f3610337565b005b61020f600480360381019061020a9190611376565b610366565b005b5f61021b82610395565b9050919050565b5f5481565b5f5f610232836103a6565b91509150915091565b5f6001905090565b61024d5f546103c4565b565b5f610259826103ea565b90505f61027961026a835f54610412565b836102745f61045b565b61046d565b90506102865f54826104cf565b5f819055506102955f54610518565b61029f5f54610599565b505050565b60015481565b6102bd5f546102b8836103ea565b61061a565b5f819055506102cc5f54610518565b6102d65f54610599565b50565b6102ec5f546102e7836103ea565b610663565b5f819055506102fb5f54610518565b6103055f54610599565b50565b610311816103ea565b5f819055505f545f1c60018190555061032a5f54610518565b6103345f54610599565b50565b61034b5f54610346600161045b565b610663565b5f8190555061035a5f54610518565b6103645f54610599565b565b61036f8161045b565b5f819055505f545f1c6001819055506103885f54610518565b6103925f54610599565b50565b5f61039f826106ac565b9050919050565b5f5f5f5f6103b385610742565b915091508181935093505050915091565b6103cd816107da565b6103dd576103da5f61045b565b90505b6103e6816107eb565b5050565b5f6103fa82604001516004610872565b61040b610406836108c2565b610904565b9050919050565b5f61041c836107da565b61042c576104295f61045b565b92505b610435826107da565b610445576104425f61045b565b91505b61045360048484601361099d565b905092915050565b5f610466825f610a8e565b9050919050565b5f61047784610aa8565b610487576104845f610ab9565b93505b610490836107da565b6104a05761049d5f61045b565b92505b6104a9826107da565b6104b9576104b65f61045b565b91505b6104c66004858585610acb565b90509392505050565b5f6104d9836107da565b6104e9576104e65f61045b565b92505b6104f2826107da565b610502576104ff5f61045b565b91505b61051060048484600761099d565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c306040518363ffffffff1660e01b81526004016105699291906113e0565b5f604051808303815f87803b158015610580575f5ffd5b505af1158015610592573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c336040518363ffffffff1660e01b81526004016105ea9291906113e0565b5f604051808303815f87803b158015610601575f5ffd5b505af1158015610613573d5f5f3e3d5ffd5b5050505050565b5f610624836107da565b610634576106315f61045b565b92505b61063d826107da565b61064d5761064a5f61045b565b91505b61065b60048484600f61099d565b905092915050565b5f61066d836107da565b61067d5761067a5f61045b565b92505b610686826107da565b610696576106935f61045b565b91505b6106a460048484600861099d565b905092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f835f1c6040518263ffffffff1660e01b81526004016106fc919061135d565b602060405180830381865afa158015610717573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073b919061141b565b9050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9845f1c6040518263ffffffff1660e01b8152600401610793919061135d565b6040805180830381865afa1580156107ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d19190611470565b91509150915091565b5f6107e482610bbe565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166308289827835f1c336040518363ffffffff1660e01b815260040161083d9291906113e0565b5f604051808303815f87803b158015610854575f5ffd5b505af1158015610866573d5f5f3e3d5ffd5b50505050819050919050565b8060ff168260ff16146108be5781816040517f67cf30710000000000000000000000000000000000000000000000000000000081526004016108b59291906114bd565b60405180910390fd5b5050565b6108ca610f65565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016109549291906115c2565b6020604051808303815f875af1158015610970573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610994919061141b565b5f1b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd86846109da8888610bcc565b5f67ffffffffffffffff8111156109f4576109f36110dd565b5b604051908082528060200260200182016040528015610a225781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610a42949392919061170b565b6020604051808303815f875af1158015610a5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a82919061141b565b5f1b9050949350505050565b5f5f610a9c84600485610c6a565b90508091505092915050565b5f610ab282610bbe565b9050919050565b5f610ac4825f610d67565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610b0a888888610d90565b5f67ffffffffffffffff811115610b2457610b236110dd565b5b604051908082528060200260200182016040528015610b525781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610b72949392919061170b565b6020604051808303815f875af1158015610b8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb2919061141b565b5f1b9050949350505050565b5f5f5f1b8214159050919050565b60605f600267ffffffffffffffff811115610bea57610be96110dd565b5b604051908082528060200260200182016040528015610c185781602001602082028036833780820191505090505b509050835f1c815f81518110610c3157610c3061175c565b5b602002602001018181525050825f1c81600181518110610c5457610c5361175c565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610cb857610cb76110dd565b5b604051908082528060200260200182016040528015610ce65781602001602082028036833780820191505090505b50610cfd898960ff16610cf88a610e52565b610ea9565b6040518563ffffffff1660e01b8152600401610d1c949392919061170b565b6020604051808303815f875af1158015610d38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5c919061141b565b5f1b90509392505050565b5f5f5f90508315610d7757600190505b5f610d83825f86610c6a565b9050809250505092915050565b60605f600367ffffffffffffffff811115610dae57610dad6110dd565b5b604051908082528060200260200182016040528015610ddc5781602001602082028036833780820191505090505b509050845f1c815f81518110610df557610df461175c565b5b602002602001018181525050835f1c81600181518110610e1857610e1761175c565b5b602002602001018181525050825f1c81600281518110610e3b57610e3a61175c565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610e9b57816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610e9291906117a4565b60405180910390fd5b8163ffffffff169050919050565b60605f600367ffffffffffffffff811115610ec757610ec66110dd565b5b604051908082528060200260200182016040528015610ef55781602001602082028036833780820191505090505b50905084815f81518110610f0c57610f0b61175c565b5b6020026020010181815250508381600181518110610f2d57610f2c61175c565b5b6020026020010181815250508281600281518110610f4e57610f4d61175c565b5b602002602001018181525050809150509392505050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610fb381610fa1565b8114610fbd575f5ffd5b50565b5f81359050610fce81610faa565b92915050565b5f60208284031215610fe957610fe8610f99565b5b5f610ff684828501610fc0565b91505092915050565b5f63ffffffff82169050919050565b61101781610fff565b82525050565b5f6020820190506110305f83018461100e565b92915050565b5f61104082610fa1565b9050919050565b61105081611036565b82525050565b5f6020820190506110695f830184611047565b92915050565b5f8115159050919050565b6110838161106f565b82525050565b5f60408201905061109c5f83018561100e565b6110a9602083018461107a565b9392505050565b5f6020820190506110c35f83018461107a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611113826110cd565b810181811067ffffffffffffffff82111715611132576111316110dd565b5b80604052505050565b5f611144610f90565b9050611150828261110a565b919050565b5f5ffd5b5f819050919050565b61116b81611159565b8114611175575f5ffd5b50565b5f8135905061118681611162565b92915050565b5f60ff82169050919050565b6111a18161118c565b81146111ab575f5ffd5b50565b5f813590506111bc81611198565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156111e4576111e36110dd565b5b6111ed826110cd565b9050602081019050919050565b828183375f83830152505050565b5f61121a611215846111ca565b61113b565b905082815260208101848484011115611236576112356111c6565b5b6112418482856111fa565b509392505050565b5f82601f83011261125d5761125c6111c2565b5b813561126d848260208601611208565b91505092915050565b5f6080828403121561128b5761128a6110c9565b5b611295608061113b565b90505f6112a484828501611178565b5f8301525060206112b7848285016111ae565b60208301525060406112cb848285016111ae565b604083015250606082013567ffffffffffffffff8111156112ef576112ee611155565b5b6112fb84828501611249565b60608301525092915050565b5f6020828403121561131c5761131b610f99565b5b5f82013567ffffffffffffffff81111561133957611338610f9d565b5b61134584828501611276565b91505092915050565b61135781611159565b82525050565b5f6020820190506113705f83018461134e565b92915050565b5f6020828403121561138b5761138a610f99565b5b5f61139884828501611178565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113ca826113a1565b9050919050565b6113da816113c0565b82525050565b5f6040820190506113f35f83018561134e565b61140060208301846113d1565b9392505050565b5f8151905061141581611162565b92915050565b5f602082840312156114305761142f610f99565b5b5f61143d84828501611407565b91505092915050565b61144f8161106f565b8114611459575f5ffd5b50565b5f8151905061146a81611446565b92915050565b5f5f6040838503121561148657611485610f99565b5b5f61149385828601611407565b92505060206114a48582860161145c565b9150509250929050565b6114b78161118c565b82525050565b5f6040820190506114d05f8301856114ae565b6114dd60208301846114ae565b9392505050565b6114ed81611159565b82525050565b6114fc8161118c565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61153482611502565b61153e818561150c565b935061154e81856020860161151c565b611557816110cd565b840191505092915050565b5f608083015f8301516115775f8601826114e4565b50602083015161158a60208601826114f3565b50604083015161159d60408601826114f3565b50606083015184820360608601526115b5828261152a565b9150508091505092915050565b5f6040820190508181035f8301526115da8185611562565b90506115e960208301846113d1565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020811061162e5761162d6115f0565b5b50565b5f81905061163e8261161d565b919050565b5f61164d82611631565b9050919050565b61165d81611643565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61169783836114e4565b60208301905092915050565b5f602082019050919050565b5f6116b982611663565b6116c3818561166d565b93506116ce8361167d565b805f5b838110156116fe5781516116e5888261168c565b97506116f0836116a3565b9250506001810190506116d1565b5085935050505092915050565b5f60808201905061171e5f8301876114ae565b61172b6020830186611654565b818103604083015261173d81856116af565b9050818103606083015261175181846116af565b905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b61179e81611789565b82525050565b5f6020820190506117b75f830184611795565b9291505056fea26469706673582212209942519ddd7cca9e972860438de52cec7fd3a8b689e91a0e56947bafe464b30464736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/mock-contracts/src/index.ts b/packages/mock-contracts/src/index.ts index 1b3d69ba..439e279f 100644 --- a/packages/mock-contracts/src/index.ts +++ b/packages/mock-contracts/src/index.ts @@ -2,5 +2,5 @@ export * from './types'; export * from './MockTaskManager'; export * from './MockACL'; export * from './MockZkVerifier'; -export * from './MockQueryDecrypter'; +export * from './MockThresholdNetwork'; export * from './TestBed'; diff --git a/packages/sdk/core/decrypt/MockQueryDecrypterAbi.ts b/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts similarity index 80% rename from packages/sdk/core/decrypt/MockQueryDecrypterAbi.ts rename to packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts index e3d3d8f8..13eb8bdc 100644 --- a/packages/sdk/core/decrypt/MockQueryDecrypterAbi.ts +++ b/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts @@ -1,4 +1,4 @@ -export const MockQueryDecrypterAbi = [ +export const MockThresholdNetworkAbi = [ { type: 'function', name: 'acl', @@ -45,11 +45,7 @@ export const MockQueryDecrypterAbi = [ { name: 'expiration', type: 'uint64', internalType: 'uint64' }, { name: 'recipient', type: 'address', internalType: 'address' }, { name: 'validatorId', type: 'uint256', internalType: 'uint256' }, - { - name: 'validatorContract', - type: 'address', - internalType: 'address', - }, + { name: 'validatorContract', type: 'address', internalType: 'address' }, { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' }, { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' }, { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' }, @@ -78,11 +74,7 @@ export const MockQueryDecrypterAbi = [ { name: 'expiration', type: 'uint64', internalType: 'uint64' }, { name: 'recipient', type: 'address', internalType: 'address' }, { name: 'validatorId', type: 'uint256', internalType: 'uint256' }, - { - name: 'validatorContract', - type: 'address', - internalType: 'address', - }, + { name: 'validatorContract', type: 'address', internalType: 'address' }, { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' }, { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' }, { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' }, @@ -106,13 +98,6 @@ export const MockQueryDecrypterAbi = [ outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], stateMutability: 'pure', }, - { - type: 'function', - name: 'taskManager', - inputs: [], - outputs: [{ name: '', type: 'address', internalType: 'contract TaskManager' }], - stateMutability: 'view', - }, { type: 'function', name: 'unseal', @@ -123,7 +108,33 @@ export const MockQueryDecrypterAbi = [ outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], stateMutability: 'pure', }, - { type: 'error', name: 'NotAllowed', inputs: [] }, - { type: 'error', name: 'SealingKeyInvalid', inputs: [] }, - { type: 'error', name: 'SealingKeyMissing', inputs: [] }, + { + type: 'function', + name: 'mockAcl', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract MockACL' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mockTaskManager', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract MockTaskManager' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mockQueryDecrypt', + inputs: [ + { name: 'ctHash', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: 'issuer', type: 'address', internalType: 'address' }, + ], + outputs: [ + { name: 'allowed', type: 'bool', internalType: 'bool' }, + { name: 'error', type: 'string', internalType: 'string' }, + { name: '', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'view', + }, ] as const; diff --git a/packages/sdk/core/decrypt/cofheMocksSealOutput.ts b/packages/sdk/core/decrypt/cofheMocksSealOutput.ts index 1ebeda12..9535d195 100644 --- a/packages/sdk/core/decrypt/cofheMocksSealOutput.ts +++ b/packages/sdk/core/decrypt/cofheMocksSealOutput.ts @@ -2,7 +2,7 @@ import { type Permit, PermitUtils } from '@/permits'; import { type PublicClient } from 'viem'; import { sleep } from '../utils.js'; -import { MockQueryDecrypterAbi } from './MockQueryDecrypterAbi.js'; +import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js'; import { FheTypes } from '../types.js'; import { CofheError, CofheErrorCode } from '../error.js'; import { MOCKS_QUERY_DECRYPTER_ADDRESS } from '../consts.js'; @@ -28,7 +28,7 @@ export async function cofheMocksSealOutput( const [allowed, error, result] = await publicClient.readContract({ address: MOCKS_QUERY_DECRYPTER_ADDRESS, - abi: MockQueryDecrypterAbi, + abi: MockThresholdNetworkAbi, functionName: 'querySealOutput', args: [ctHash, BigInt(utype), permissionWithBigInts], }); From 81e057d3396590fb6637c73b5c56d94064df1319 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 15:43:54 +0200 Subject: [PATCH 14/24] test: involve TestBed into publishDecryptResult --- .../test/decrypt-with-proof.test.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts index 26321c31..753c9d43 100644 --- a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts +++ b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts @@ -1,9 +1,9 @@ import hre from 'hardhat'; import { expect } from 'chai'; import { TASK_COFHE_MOCKS_DEPLOY } from './consts'; -import { Wallet, keccak256, solidityPacked } from 'ethers'; +import { Wallet, keccak256, solidityPacked, toBeHex } from 'ethers'; -// Minimal happy-path test for MockTaskManager.publishDecryptResult +// Minimal happy-path test for TestBed.publishDecryptResult // This verifies we can publish a decrypt result with a valid signature and read it back. describe('Decrypt With Proof Test', () => { @@ -11,6 +11,7 @@ describe('Decrypt With Proof Test', () => { await hre.run(TASK_COFHE_MOCKS_DEPLOY); const taskManager = await hre.cofhe.mocks.getMockTaskManager(); + const testBed = await hre.cofhe.mocks.getTestBed(); // Signer used by publishDecryptResult signature verification const signerPrivateKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; @@ -30,19 +31,23 @@ describe('Decrypt With Proof Test', () => { const result = 424242n; + const ctHashBytes32 = toBeHex(ctHash, 32); + const digest = keccak256( solidityPacked( ['uint256', 'uint32', 'uint64', 'bytes32'], - [result, utype, BigInt((await hre.ethers.provider.getNetwork()).chainId), hre.ethers.toBeHex(ctHash, 32)] + [result, utype, BigInt((await hre.ethers.provider.getNetwork()).chainId), ctHashBytes32] ) ); const sig = signerWallet.signingKey.sign(digest); const signature = hre.ethers.concat([sig.r, sig.s, hre.ethers.toBeHex(sig.v, 1)]); - await taskManager.publishDecryptResult(ctHash, result, signature); + const tx = await testBed.publishDecryptResult(ctHashBytes32, result, signature); + await tx.wait(); - const onchain = await taskManager.getDecryptResult(ctHash); - expect(onchain).to.equal(result); + const [value, decrypted] = await testBed.getDecryptResultSafe(ctHashBytes32); + expect(decrypted).to.equal(true); + expect(value).to.equal(result); }); }); From cbdf62d85aeb6506ad94ff94aeabe0d911c6216b Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 15:44:00 +0200 Subject: [PATCH 15/24] test: involve TestBed into publishDecryptResult --- packages/mock-contracts/contracts/TestBed.sol | 5 ++++ packages/mock-contracts/src/TestBed.ts | 25 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/mock-contracts/contracts/TestBed.sol b/packages/mock-contracts/contracts/TestBed.sol index 51d9819f..2fc2cfe2 100644 --- a/packages/mock-contracts/contracts/TestBed.sol +++ b/packages/mock-contracts/contracts/TestBed.sol @@ -90,4 +90,9 @@ contract TestBed { function getDecryptResultSafe(euint32 input1) public view returns (uint32 value, bool decrypted) { return FHE.getDecryptResultSafe(input1); } + + /// @notice Publishes a decrypt result for an encrypted handle. + function publishDecryptResult(euint32 input, uint32 result, bytes memory signature) external { + FHE.publishDecryptResult(input, result, signature); + } } diff --git a/packages/mock-contracts/src/TestBed.ts b/packages/mock-contracts/src/TestBed.ts index 54e87bf1..2105b078 100644 --- a/packages/mock-contracts/src/TestBed.ts +++ b/packages/mock-contracts/src/TestBed.ts @@ -172,6 +172,29 @@ export const TestBedArtifact = { ], stateMutability: 'view', }, + { + type: 'function', + name: 'publishDecryptResult', + inputs: [ + { + name: 'input', + type: 'bytes32', + internalType: 'euint32', + }, + { + name: 'result', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', name: 'setNumber', @@ -284,5 +307,5 @@ export const TestBedArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b50600436106100b2575f3560e01c806367c651741161006f57806367c651741461017957806384f091db1461019757806384ff25c6146101b3578063b5872e8c146101cf578063d09de08a146101eb578063d7a0faa2146101f5576100b2565b80631292f65a146100b657806319d8a05b146100e6578063260ec88914610104578063267c4ae4146101355780633983d43014610153578063647096091461015d575b5f5ffd5b6100d060048036038101906100cb9190610fd4565b610211565b6040516100dd919061101d565b60405180910390f35b6100ee610222565b6040516100fb9190611056565b60405180910390f35b61011e60048036038101906101199190610fd4565b610227565b60405161012c929190611089565b60405180910390f35b61013d61023b565b60405161014a91906110b0565b60405180910390f35b61015b610243565b005b61017760048036038101906101729190611307565b61024f565b005b6101816102a4565b60405161018e919061135d565b60405180910390f35b6101b160048036038101906101ac9190611307565b6102aa565b005b6101cd60048036038101906101c89190611307565b6102d9565b005b6101e960048036038101906101e49190611307565b610308565b005b6101f3610337565b005b61020f600480360381019061020a9190611376565b610366565b005b5f61021b82610395565b9050919050565b5f5481565b5f5f610232836103a6565b91509150915091565b5f6001905090565b61024d5f546103c4565b565b5f610259826103ea565b90505f61027961026a835f54610412565b836102745f61045b565b61046d565b90506102865f54826104cf565b5f819055506102955f54610518565b61029f5f54610599565b505050565b60015481565b6102bd5f546102b8836103ea565b61061a565b5f819055506102cc5f54610518565b6102d65f54610599565b50565b6102ec5f546102e7836103ea565b610663565b5f819055506102fb5f54610518565b6103055f54610599565b50565b610311816103ea565b5f819055505f545f1c60018190555061032a5f54610518565b6103345f54610599565b50565b61034b5f54610346600161045b565b610663565b5f8190555061035a5f54610518565b6103645f54610599565b565b61036f8161045b565b5f819055505f545f1c6001819055506103885f54610518565b6103925f54610599565b50565b5f61039f826106ac565b9050919050565b5f5f5f5f6103b385610742565b915091508181935093505050915091565b6103cd816107da565b6103dd576103da5f61045b565b90505b6103e6816107eb565b5050565b5f6103fa82604001516004610872565b61040b610406836108c2565b610904565b9050919050565b5f61041c836107da565b61042c576104295f61045b565b92505b610435826107da565b610445576104425f61045b565b91505b61045360048484601361099d565b905092915050565b5f610466825f610a8e565b9050919050565b5f61047784610aa8565b610487576104845f610ab9565b93505b610490836107da565b6104a05761049d5f61045b565b92505b6104a9826107da565b6104b9576104b65f61045b565b91505b6104c66004858585610acb565b90509392505050565b5f6104d9836107da565b6104e9576104e65f61045b565b92505b6104f2826107da565b610502576104ff5f61045b565b91505b61051060048484600761099d565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c306040518363ffffffff1660e01b81526004016105699291906113e0565b5f604051808303815f87803b158015610580575f5ffd5b505af1158015610592573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c336040518363ffffffff1660e01b81526004016105ea9291906113e0565b5f604051808303815f87803b158015610601575f5ffd5b505af1158015610613573d5f5f3e3d5ffd5b5050505050565b5f610624836107da565b610634576106315f61045b565b92505b61063d826107da565b61064d5761064a5f61045b565b91505b61065b60048484600f61099d565b905092915050565b5f61066d836107da565b61067d5761067a5f61045b565b92505b610686826107da565b610696576106935f61045b565b91505b6106a460048484600861099d565b905092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f835f1c6040518263ffffffff1660e01b81526004016106fc919061135d565b602060405180830381865afa158015610717573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073b919061141b565b9050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9845f1c6040518263ffffffff1660e01b8152600401610793919061135d565b6040805180830381865afa1580156107ad573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d19190611470565b91509150915091565b5f6107e482610bbe565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166308289827835f1c336040518363ffffffff1660e01b815260040161083d9291906113e0565b5f604051808303815f87803b158015610854575f5ffd5b505af1158015610866573d5f5f3e3d5ffd5b50505050819050919050565b8060ff168260ff16146108be5781816040517f67cf30710000000000000000000000000000000000000000000000000000000081526004016108b59291906114bd565b60405180910390fd5b5050565b6108ca610f65565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016109549291906115c2565b6020604051808303815f875af1158015610970573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610994919061141b565b5f1b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd86846109da8888610bcc565b5f67ffffffffffffffff8111156109f4576109f36110dd565b5b604051908082528060200260200182016040528015610a225781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610a42949392919061170b565b6020604051808303815f875af1158015610a5e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a82919061141b565b5f1b9050949350505050565b5f5f610a9c84600485610c6a565b90508091505092915050565b5f610ab282610bbe565b9050919050565b5f610ac4825f610d67565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610b0a888888610d90565b5f67ffffffffffffffff811115610b2457610b236110dd565b5b604051908082528060200260200182016040528015610b525781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610b72949392919061170b565b6020604051808303815f875af1158015610b8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb2919061141b565b5f1b9050949350505050565b5f5f5f1b8214159050919050565b60605f600267ffffffffffffffff811115610bea57610be96110dd565b5b604051908082528060200260200182016040528015610c185781602001602082028036833780820191505090505b509050835f1c815f81518110610c3157610c3061175c565b5b602002602001018181525050825f1c81600181518110610c5457610c5361175c565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610cb857610cb76110dd565b5b604051908082528060200260200182016040528015610ce65781602001602082028036833780820191505090505b50610cfd898960ff16610cf88a610e52565b610ea9565b6040518563ffffffff1660e01b8152600401610d1c949392919061170b565b6020604051808303815f875af1158015610d38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5c919061141b565b5f1b90509392505050565b5f5f5f90508315610d7757600190505b5f610d83825f86610c6a565b9050809250505092915050565b60605f600367ffffffffffffffff811115610dae57610dad6110dd565b5b604051908082528060200260200182016040528015610ddc5781602001602082028036833780820191505090505b509050845f1c815f81518110610df557610df461175c565b5b602002602001018181525050835f1c81600181518110610e1857610e1761175c565b5b602002602001018181525050825f1c81600281518110610e3b57610e3a61175c565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610e9b57816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610e9291906117a4565b60405180910390fd5b8163ffffffff169050919050565b60605f600367ffffffffffffffff811115610ec757610ec66110dd565b5b604051908082528060200260200182016040528015610ef55781602001602082028036833780820191505090505b50905084815f81518110610f0c57610f0b61175c565b5b6020026020010181815250508381600181518110610f2d57610f2c61175c565b5b6020026020010181815250508281600281518110610f4e57610f4d61175c565b5b602002602001018181525050809150509392505050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610fb381610fa1565b8114610fbd575f5ffd5b50565b5f81359050610fce81610faa565b92915050565b5f60208284031215610fe957610fe8610f99565b5b5f610ff684828501610fc0565b91505092915050565b5f63ffffffff82169050919050565b61101781610fff565b82525050565b5f6020820190506110305f83018461100e565b92915050565b5f61104082610fa1565b9050919050565b61105081611036565b82525050565b5f6020820190506110695f830184611047565b92915050565b5f8115159050919050565b6110838161106f565b82525050565b5f60408201905061109c5f83018561100e565b6110a9602083018461107a565b9392505050565b5f6020820190506110c35f83018461107a565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611113826110cd565b810181811067ffffffffffffffff82111715611132576111316110dd565b5b80604052505050565b5f611144610f90565b9050611150828261110a565b919050565b5f5ffd5b5f819050919050565b61116b81611159565b8114611175575f5ffd5b50565b5f8135905061118681611162565b92915050565b5f60ff82169050919050565b6111a18161118c565b81146111ab575f5ffd5b50565b5f813590506111bc81611198565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156111e4576111e36110dd565b5b6111ed826110cd565b9050602081019050919050565b828183375f83830152505050565b5f61121a611215846111ca565b61113b565b905082815260208101848484011115611236576112356111c6565b5b6112418482856111fa565b509392505050565b5f82601f83011261125d5761125c6111c2565b5b813561126d848260208601611208565b91505092915050565b5f6080828403121561128b5761128a6110c9565b5b611295608061113b565b90505f6112a484828501611178565b5f8301525060206112b7848285016111ae565b60208301525060406112cb848285016111ae565b604083015250606082013567ffffffffffffffff8111156112ef576112ee611155565b5b6112fb84828501611249565b60608301525092915050565b5f6020828403121561131c5761131b610f99565b5b5f82013567ffffffffffffffff81111561133957611338610f9d565b5b61134584828501611276565b91505092915050565b61135781611159565b82525050565b5f6020820190506113705f83018461134e565b92915050565b5f6020828403121561138b5761138a610f99565b5b5f61139884828501611178565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113ca826113a1565b9050919050565b6113da816113c0565b82525050565b5f6040820190506113f35f83018561134e565b61140060208301846113d1565b9392505050565b5f8151905061141581611162565b92915050565b5f602082840312156114305761142f610f99565b5b5f61143d84828501611407565b91505092915050565b61144f8161106f565b8114611459575f5ffd5b50565b5f8151905061146a81611446565b92915050565b5f5f6040838503121561148657611485610f99565b5b5f61149385828601611407565b92505060206114a48582860161145c565b9150509250929050565b6114b78161118c565b82525050565b5f6040820190506114d05f8301856114ae565b6114dd60208301846114ae565b9392505050565b6114ed81611159565b82525050565b6114fc8161118c565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61153482611502565b61153e818561150c565b935061154e81856020860161151c565b611557816110cd565b840191505092915050565b5f608083015f8301516115775f8601826114e4565b50602083015161158a60208601826114f3565b50604083015161159d60408601826114f3565b50606083015184820360608601526115b5828261152a565b9150508091505092915050565b5f6040820190508181035f8301526115da8185611562565b90506115e960208301846113d1565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020811061162e5761162d6115f0565b5b50565b5f81905061163e8261161d565b919050565b5f61164d82611631565b9050919050565b61165d81611643565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61169783836114e4565b60208301905092915050565b5f602082019050919050565b5f6116b982611663565b6116c3818561166d565b93506116ce8361167d565b805f5b838110156116fe5781516116e5888261168c565b97506116f0836116a3565b9250506001810190506116d1565b5085935050505092915050565b5f60808201905061171e5f8301876114ae565b61172b6020830186611654565b818103604083015261173d81856116af565b9050818103606083015261175181846116af565b905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b61179e81611789565b82525050565b5f6020820190506117b75f830184611795565b9291505056fea26469706673582212209942519ddd7cca9e972860438de52cec7fd3a8b689e91a0e56947bafe464b30464736f6c634300081c0033', + '0x608060405234801561000f575f5ffd5b50600436106100cd575f3560e01c806367c651741161008a57806388762d811161006457806388762d81146101ea578063b5872e8c14610206578063d09de08a14610222578063d7a0faa21461022c576100cd565b806367c651741461019457806384f091db146101b257806384ff25c6146101ce576100cd565b80631292f65a146100d157806319d8a05b14610101578063260ec8891461011f578063267c4ae4146101505780633983d4301461016e5780636470960914610178575b5f5ffd5b6100eb60048036038101906100e691906110b6565b610248565b6040516100f891906110ff565b60405180910390f35b610109610259565b6040516101169190611138565b60405180910390f35b610139600480360381019061013491906110b6565b61025e565b60405161014792919061116b565b60405180910390f35b610158610272565b6040516101659190611192565b60405180910390f35b61017661027a565b005b610192600480360381019061018d91906113e9565b610286565b005b61019c6102db565b6040516101a9919061143f565b60405180910390f35b6101cc60048036038101906101c791906113e9565b6102e1565b005b6101e860048036038101906101e391906113e9565b610310565b005b61020460048036038101906101ff9190611482565b61033f565b005b610220600480360381019061021b91906113e9565b61034f565b005b61022a61037e565b005b610246600480360381019061024191906114ee565b6103ad565b005b5f610252826103dc565b9050919050565b5f5481565b5f5f610269836103ed565b91509150915091565b5f6001905090565b6102845f5461040b565b565b5f61029082610431565b90505f6102b06102a1835f54610459565b836102ab5f6104a2565b6104b4565b90506102bd5f5482610516565b5f819055506102cc5f5461055f565b6102d65f546105e0565b505050565b60015481565b6102f45f546102ef83610431565b610661565b5f819055506103035f5461055f565b61030d5f546105e0565b50565b6103235f5461031e83610431565b6106aa565b5f819055506103325f5461055f565b61033c5f546105e0565b50565b61034a8383836106f3565b505050565b61035881610431565b5f819055505f545f1c6001819055506103715f5461055f565b61037b5f546105e0565b50565b6103925f5461038d60016104a2565b6106aa565b5f819055506103a15f5461055f565b6103ab5f546105e0565b565b6103b6816104a2565b5f819055505f545f1c6001819055506103cf5f5461055f565b6103d95f546105e0565b50565b5f6103e682610709565b9050919050565b5f5f5f5f6103fa8561079f565b915091508181935093505050915091565b61041481610837565b610424576104215f6104a2565b90505b61042d81610848565b5050565b5f610441826040015160046108cf565b61045261044d8361091f565b610961565b9050919050565b5f61046383610837565b610473576104705f6104a2565b92505b61047c82610837565b61048c576104895f6104a2565b91505b61049a6004848460136109fa565b905092915050565b5f6104ad825f610aeb565b9050919050565b5f6104be84610b05565b6104ce576104cb5f610b16565b93505b6104d783610837565b6104e7576104e45f6104a2565b92505b6104f082610837565b610500576104fd5f6104a2565b91505b61050d6004858585610b28565b90509392505050565b5f61052083610837565b6105305761052d5f6104a2565b92505b61053982610837565b610549576105465f6104a2565b91505b6105576004848460076109fa565b905092915050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c306040518363ffffffff1660e01b81526004016105b0929190611558565b5f604051808303815f87803b1580156105c7575f5ffd5b505af11580156105d9573d5f5f3e3d5ffd5b5050505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166365d0509c825f1c336040518363ffffffff1660e01b8152600401610631929190611558565b5f604051808303815f87803b158015610648575f5ffd5b505af115801561065a573d5f5f3e3d5ffd5b5050505050565b5f61066b83610837565b61067b576106785f6104a2565b92505b61068482610837565b610694576106915f6104a2565b91505b6106a260048484600f6109fa565b905092915050565b5f6106b483610837565b6106c4576106c15f6104a2565b92505b6106cd82610837565b6106dd576106da5f6104a2565b91505b6106eb6004848460086109fa565b905092915050565b610704838363ffffffff1683610c1b565b505050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663f6bc7f3f835f1c6040518263ffffffff1660e01b8152600401610759919061143f565b602060405180830381865afa158015610774573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107989190611593565b9050919050565b5f5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff1663458693c9845f1c6040518263ffffffff1660e01b81526004016107f0919061143f565b6040805180830381865afa15801561080a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061082e91906115e8565b91509150915091565b5f61084182610ca0565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166308289827835f1c336040518363ffffffff1660e01b815260040161089a929190611558565b5f604051808303815f87803b1580156108b1575f5ffd5b505af11580156108c3573d5f5f3e3d5ffd5b50505050819050919050565b8060ff168260ff161461091b5781816040517f67cf3071000000000000000000000000000000000000000000000000000000008152600401610912929190611635565b60405180910390fd5b5050565b610927611047565b6040518060800160405280835f01518152602001836020015160ff168152602001600460ff16815260200183606001518152509050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166327f9c76283336040518363ffffffff1660e01b81526004016109b192919061173a565b6020604051808303815f875af11580156109cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f19190611593565b5f1b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd8684610a378888610cae565b5f67ffffffffffffffff811115610a5157610a506111bf565b5b604051908082528060200260200182016040528015610a7f5781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610a9f9493929190611883565b6020604051808303815f875af1158015610abb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610adf9190611593565b5f1b9050949350505050565b5f5f610af984600485610d4c565b90508091505092915050565b5f610b0f82610ca0565b9050919050565b5f610b21825f610e49565b9050919050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd866004610b67888888610e72565b5f67ffffffffffffffff811115610b8157610b806111bf565b5b604051908082528060200260200182016040528015610baf5781602001602082028036833780820191505090505b506040518563ffffffff1660e01b8152600401610bcf9493929190611883565b6020604051808303815f875af1158015610beb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0f9190611593565b5f1b9050949350505050565b73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff166318683701845f1c84846040518463ffffffff1660e01b8152600401610c6e9392919061191c565b5f604051808303815f87803b158015610c85575f5ffd5b505af1158015610c97573d5f5f3e3d5ffd5b50505050505050565b5f5f5f1b8214159050919050565b60605f600267ffffffffffffffff811115610ccc57610ccb6111bf565b5b604051908082528060200260200182016040528015610cfa5781602001602082028036833780820191505090505b509050835f1c815f81518110610d1357610d12611958565b5b602002602001018181525050825f1c81600181518110610d3657610d35611958565b5b6020026020010181815250508091505092915050565b5f73ea30c4b8b44078bbf8a6ef5b9f1ec1626c7848d973ffffffffffffffffffffffffffffffffffffffff16631888debd84601a5f67ffffffffffffffff811115610d9a57610d996111bf565b5b604051908082528060200260200182016040528015610dc85781602001602082028036833780820191505090505b50610ddf898960ff16610dda8a610f34565b610f8b565b6040518563ffffffff1660e01b8152600401610dfe9493929190611883565b6020604051808303815f875af1158015610e1a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e3e9190611593565b5f1b90509392505050565b5f5f5f90508315610e5957600190505b5f610e65825f86610d4c565b9050809250505092915050565b60605f600367ffffffffffffffff811115610e9057610e8f6111bf565b5b604051908082528060200260200182016040528015610ebe5781602001602082028036833780820191505090505b509050845f1c815f81518110610ed757610ed6611958565b5b602002602001018181525050835f1c81600181518110610efa57610ef9611958565b5b602002602001018181525050825f1c81600281518110610f1d57610f1c611958565b5b602002602001018181525050809150509392505050565b5f5f8260030b1215610f7d57816040517f8f568bf8000000000000000000000000000000000000000000000000000000008152600401610f7491906119a0565b60405180910390fd5b8163ffffffff169050919050565b60605f600367ffffffffffffffff811115610fa957610fa86111bf565b5b604051908082528060200260200182016040528015610fd75781602001602082028036833780820191505090505b50905084815f81518110610fee57610fed611958565b5b602002602001018181525050838160018151811061100f5761100e611958565b5b60200260200101818152505082816002815181106110305761102f611958565b5b602002602001018181525050809150509392505050565b60405180608001604052805f81526020015f60ff1681526020015f60ff168152602001606081525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61109581611083565b811461109f575f5ffd5b50565b5f813590506110b08161108c565b92915050565b5f602082840312156110cb576110ca61107b565b5b5f6110d8848285016110a2565b91505092915050565b5f63ffffffff82169050919050565b6110f9816110e1565b82525050565b5f6020820190506111125f8301846110f0565b92915050565b5f61112282611083565b9050919050565b61113281611118565b82525050565b5f60208201905061114b5f830184611129565b92915050565b5f8115159050919050565b61116581611151565b82525050565b5f60408201905061117e5f8301856110f0565b61118b602083018461115c565b9392505050565b5f6020820190506111a55f83018461115c565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6111f5826111af565b810181811067ffffffffffffffff82111715611214576112136111bf565b5b80604052505050565b5f611226611072565b905061123282826111ec565b919050565b5f5ffd5b5f819050919050565b61124d8161123b565b8114611257575f5ffd5b50565b5f8135905061126881611244565b92915050565b5f60ff82169050919050565b6112838161126e565b811461128d575f5ffd5b50565b5f8135905061129e8161127a565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156112c6576112c56111bf565b5b6112cf826111af565b9050602081019050919050565b828183375f83830152505050565b5f6112fc6112f7846112ac565b61121d565b905082815260208101848484011115611318576113176112a8565b5b6113238482856112dc565b509392505050565b5f82601f83011261133f5761133e6112a4565b5b813561134f8482602086016112ea565b91505092915050565b5f6080828403121561136d5761136c6111ab565b5b611377608061121d565b90505f6113868482850161125a565b5f83015250602061139984828501611290565b60208301525060406113ad84828501611290565b604083015250606082013567ffffffffffffffff8111156113d1576113d0611237565b5b6113dd8482850161132b565b60608301525092915050565b5f602082840312156113fe576113fd61107b565b5b5f82013567ffffffffffffffff81111561141b5761141a61107f565b5b61142784828501611358565b91505092915050565b6114398161123b565b82525050565b5f6020820190506114525f830184611430565b92915050565b611461816110e1565b811461146b575f5ffd5b50565b5f8135905061147c81611458565b92915050565b5f5f5f606084860312156114995761149861107b565b5b5f6114a6868287016110a2565b93505060206114b78682870161146e565b925050604084013567ffffffffffffffff8111156114d8576114d761107f565b5b6114e48682870161132b565b9150509250925092565b5f602082840312156115035761150261107b565b5b5f6115108482850161125a565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61154282611519565b9050919050565b61155281611538565b82525050565b5f60408201905061156b5f830185611430565b6115786020830184611549565b9392505050565b5f8151905061158d81611244565b92915050565b5f602082840312156115a8576115a761107b565b5b5f6115b58482850161157f565b91505092915050565b6115c781611151565b81146115d1575f5ffd5b50565b5f815190506115e2816115be565b92915050565b5f5f604083850312156115fe576115fd61107b565b5b5f61160b8582860161157f565b925050602061161c858286016115d4565b9150509250929050565b61162f8161126e565b82525050565b5f6040820190506116485f830185611626565b6116556020830184611626565b9392505050565b6116658161123b565b82525050565b6116748161126e565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6116ac8261167a565b6116b68185611684565b93506116c6818560208601611694565b6116cf816111af565b840191505092915050565b5f608083015f8301516116ef5f86018261165c565b506020830151611702602086018261166b565b506040830151611715604086018261166b565b506060830151848203606086015261172d82826116a2565b9150508091505092915050565b5f6040820190508181035f83015261175281856116da565b90506117616020830184611549565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b602081106117a6576117a5611768565b5b50565b5f8190506117b682611795565b919050565b5f6117c5826117a9565b9050919050565b6117d5816117bb565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61180f838361165c565b60208301905092915050565b5f602082019050919050565b5f611831826117db565b61183b81856117e5565b9350611846836117f5565b805f5b8381101561187657815161185d8882611804565b97506118688361181b565b925050600181019050611849565b5085935050505092915050565b5f6080820190506118965f830187611626565b6118a360208301866117cc565b81810360408301526118b58185611827565b905081810360608301526118c98184611827565b905095945050505050565b5f82825260208201905092915050565b5f6118ee8261167a565b6118f881856118d4565b9350611908818560208601611694565b611911816111af565b840191505092915050565b5f60608201905061192f5f830186611430565b61193c6020830185611430565b818103604083015261194e81846118e4565b9050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8160030b9050919050565b61199a81611985565b82525050565b5f6020820190506119b35f830184611991565b9291505056fea26469706673582212200d60db837c6988466f7b15284794c7c7d0f089a0efad8e8e1dac274d019473e764736f6c634300081c0033', } satisfies MockArtifact; From cb4717fac800de3bd9a21275683731bebf849e4d Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 16:01:58 +0200 Subject: [PATCH 16/24] chore: prepare for decryptForTx implementation (untested yet) --- .../contracts/MockThresholdNetwork.sol | 45 +++++++++++ .../contracts/foundry/CoFheTest.sol | 7 ++ .../src/MockThresholdNetwork.ts | 78 ++++++++++++++++++- .../core/decrypt/cofheMocksDecryptForTx.ts | 65 ++++++++++++++++ .../sdk/core/decrypt/decryptHandleBuilder.ts | 9 +++ 5 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts diff --git a/packages/mock-contracts/contracts/MockThresholdNetwork.sol b/packages/mock-contracts/contracts/MockThresholdNetwork.sol index e55efeac..b948dbbc 100644 --- a/packages/mock-contracts/contracts/MockThresholdNetwork.sol +++ b/packages/mock-contracts/contracts/MockThresholdNetwork.sol @@ -114,6 +114,51 @@ contract MockThresholdNetwork { return (true, '', seal(value, permission.sealingKey)); } + // DECRYPT FOR TX + + /// @notice Decrypt a ciphertext for a transaction with optional permission permit + /// @param ctHash The ciphertext hash to decrypt + /// @param permission Optional permission object; if empty (issuer == address(0)), check global allowance + /// @return allowed Whether the decryption is allowed + /// @return error Error message if decryption is not allowed + /// @return decryptedValue The decrypted plaintext value if allowed + function decryptForTx( + uint256 ctHash, + Permission memory permission + ) public view returns (bool allowed, string memory error, uint256 decryptedValue) { + bool isAllowed; + + // If permission has an issuer, use permission-based check; otherwise use global allowance check + if (permission.issuer != address(0)) { + // With permit: query TM.isAllowedWithPermission() + try mockTaskManager.isAllowedWithPermission(permission, ctHash) returns (bool _isAllowed) { + isAllowed = _isAllowed; + } catch Error(string memory reason) { + return (false, reason, 0); + } catch Panic(uint /*errorCode*/) { + return (false, 'Panic', 0); + } catch (bytes memory lowLevelData) { + return (false, decodeLowLevelReversion(lowLevelData), 0); + } + } else { + // Without permit: query TM.globallyAllowed() via ACL + try mockAcl.globalAllowed(ctHash) returns (bool _isAllowed) { + isAllowed = _isAllowed; + } catch Error(string memory reason) { + return (false, reason, 0); + } catch Panic(uint /*errorCode*/) { + return (false, 'Panic', 0); + } catch (bytes memory lowLevelData) { + return (false, decodeLowLevelReversion(lowLevelData), 0); + } + } + + if (!isAllowed) return (false, 'NotAllowed', 0); + + uint256 value = mockTaskManager.mockStorage(ctHash); + return (true, '', value); + } + // UTIL function decodeLowLevelReversion(bytes memory data) public pure returns (string memory error) { diff --git a/packages/mock-contracts/contracts/foundry/CoFheTest.sol b/packages/mock-contracts/contracts/foundry/CoFheTest.sol index 1b3293a1..9eb5af12 100644 --- a/packages/mock-contracts/contracts/foundry/CoFheTest.sol +++ b/packages/mock-contracts/contracts/foundry/CoFheTest.sol @@ -427,6 +427,13 @@ abstract contract CoFheTest is Test { return mockThresholdNetwork.querySealOutput(ctHash, hostChainId, permission); } + function decryptForTx( + uint256 ctHash, + Permission memory permission + ) public view returns (bool, string memory error, uint256) { + return mockThresholdNetwork.decryptForTx(ctHash, permission); + } + function unseal(bytes32 hashed, bytes32 key) public view returns (uint256) { return mockThresholdNetwork.unseal(hashed, key); } diff --git a/packages/mock-contracts/src/MockThresholdNetwork.ts b/packages/mock-contracts/src/MockThresholdNetwork.ts index 0a74e087..ac2dfabc 100644 --- a/packages/mock-contracts/src/MockThresholdNetwork.ts +++ b/packages/mock-contracts/src/MockThresholdNetwork.ts @@ -25,6 +25,82 @@ export const MockThresholdNetworkArtifact = { ], stateMutability: 'pure', }, + { + type: 'function', + name: 'decryptForTx', + inputs: [ + { + name: 'ctHash', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'permission', + type: 'tuple', + internalType: 'struct Permission', + components: [ + { + name: 'issuer', + type: 'address', + internalType: 'address', + }, + { + name: 'expiration', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'recipient', + type: 'address', + internalType: 'address', + }, + { + name: 'validatorId', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'validatorContract', + type: 'address', + internalType: 'address', + }, + { + name: 'sealingKey', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'issuerSignature', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'recipientSignature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: 'allowed', + type: 'bool', + internalType: 'bool', + }, + { + name: 'error', + type: 'string', + internalType: 'string', + }, + { + name: 'decryptedValue', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, { type: 'function', name: 'exists', @@ -348,5 +424,5 @@ export const MockThresholdNetworkArtifact = { }, ], deployedBytecode: - '0x608060405234801561000f575f5ffd5b506004361061009c575f3560e01c80637e0f4b5b116100645780637e0f4b5b1461015a5780638a5c8c7f14610178578063a02eb534146101a8578063a0639f54146101da578063ff6957d31461020c5761009c565b806309ba3156146100a05780631a1992a9146100d2578063267c4ae414610102578063485cc955146101205780634cdc014d1461013c575b5f5ffd5b6100ba60048036038101906100b591906110b5565b61023c565b6040516100c9939291906111aa565b60405180910390f35b6100ec60048036038101906100e791906111e6565b61051f565b6040516100f99190611224565b60405180910390f35b61010a61052d565b604051610117919061123d565b60405180910390f35b61013a60048036038101906101359190611256565b610535565b005b6101446105b8565b60405161015191906112ef565b60405180910390f35b6101626105dd565b60405161016f9190611328565b60405180910390f35b610192600480360381019061018d9190611341565b610601565b60405161019f919061138e565b60405180910390f35b6101c260048036038101906101bd91906113a7565b61060f565b6040516101d1939291906113f7565b60405180910390f35b6101f460048036038101906101ef91906110b5565b61089e565b604051610203939291906113f7565b60405180910390f35b61022660048036038101906102219190611433565b610b28565b604051610233919061147a565b60405180910390f35b5f60605f5f5f1b8460a001510361027f576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016102dc9291906115dc565b602060405180830381865afa92505050801561031657506040513d601f19601f820116820180604052508101906103139190611634565b60015b6104025761032261166b565b806308c379a003610353575061033661168a565b8061034157506103b8565b5f815f5f1b9450945094505050610516565b634e487b71036103b857610365611719565b9061037057506103b8565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610516565b3d805f81146103e2576040519150601f19603f3d011682016040523d82523d5f602084013e6103e7565b606091505b505f6103f282610b28565b5f5f1b9450945094505050610516565b8091505080610452575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610516565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104ac919061138e565b602060405180830381865afa1580156104c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104eb919061174b565b905060016104fd828860a0015161051f565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b8152600401610670929190611785565b602060405180830381865afa9250505080156106aa57506040513d601f19601f820116820180604052508101906106a79190611634565b60015b610790576106b661166b565b806308c379a0036106e557506106ca61168a565b806106d55750610748565b5f815f9450945094505050610895565b634e487b7103610748576106f7611719565b906107025750610748565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610895565b3d805f8114610772576040519150601f19603f3d011682016040523d82523d5f602084013e610777565b606091505b505f61078282610b28565b5f9450945094505050610895565b80915050806107de575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610895565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610838919061138e565b602060405180830381865afa158015610853573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610877919061174b565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b81526004016108ff9291906115dc565b602060405180830381865afa92505050801561093957506040513d601f19601f820116820180604052508101906109369190611634565b60015b610a1f5761094561166b565b806308c379a003610974575061095961168a565b8061096457506109d7565b5f815f9450945094505050610b1f565b634e487b71036109d757610986611719565b9061099157506109d7565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b1f565b3d805f8114610a01576040519150601f19603f3d011682016040523d82523d5f602084013e610a06565b606091505b505f610a1182610b28565b5f9450945094505050610b1f565b8091505080610a6d575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b1f565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610ac8919061138e565b602060405180830381865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b07919061174b565b60405180602001604052805f81525090935093509350505b93509350939050565b60605f82610b3590611806565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bc1576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f4578706972656400000000000000815250915050610d5f565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c2e5760405180606001604052806021815260200161189160219139915050610d5f565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c9b5760405180606001604052806024815260200161186d60249139915050610d5f565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d25576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c6564000000000000815250915050610d5f565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b610d8781610d75565b8114610d91575f5ffd5b50565b5f81359050610da281610d7e565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610df282610dac565b810181811067ffffffffffffffff82111715610e1157610e10610dbc565b5b80604052505050565b5f610e23610d64565b9050610e2f8282610de9565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6182610e38565b9050919050565b610e7181610e57565b8114610e7b575f5ffd5b50565b5f81359050610e8c81610e68565b92915050565b5f67ffffffffffffffff82169050919050565b610eae81610e92565b8114610eb8575f5ffd5b50565b5f81359050610ec981610ea5565b92915050565b5f819050919050565b610ee181610ecf565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff821115610f2457610f23610dbc565b5b610f2d82610dac565b9050602081019050919050565b828183375f83830152505050565b5f610f5a610f5584610f0a565b610e1a565b905082815260208101848484011115610f7657610f75610f06565b5b610f81848285610f3a565b509392505050565b5f82601f830112610f9d57610f9c610f02565b5b8135610fad848260208601610f48565b91505092915050565b5f6101008284031215610fcc57610fcb610da8565b5b610fd7610100610e1a565b90505f610fe684828501610e7e565b5f830152506020610ff984828501610ebb565b602083015250604061100d84828501610e7e565b604083015250606061102184828501610d94565b606083015250608061103584828501610e7e565b60808301525060a061104984828501610eee565b60a08301525060c082013567ffffffffffffffff81111561106d5761106c610e34565b5b61107984828501610f89565b60c08301525060e082013567ffffffffffffffff81111561109d5761109c610e34565b5b6110a984828501610f89565b60e08301525092915050565b5f5f5f606084860312156110cc576110cb610d6d565b5b5f6110d986828701610d94565b93505060206110ea86828701610d94565b925050604084013567ffffffffffffffff81111561110b5761110a610d71565b5b61111786828701610fb6565b9150509250925092565b5f8115159050919050565b61113581611121565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61116d8261113b565b6111778185611145565b9350611187818560208601611155565b61119081610dac565b840191505092915050565b6111a481610ecf565b82525050565b5f6060820190506111bd5f83018661112c565b81810360208301526111cf8185611163565b90506111de604083018461119b565b949350505050565b5f5f604083850312156111fc576111fb610d6d565b5b5f61120985828601610d94565b925050602061121a85828601610eee565b9150509250929050565b5f6020820190506112375f83018461119b565b92915050565b5f6020820190506112505f83018461112c565b92915050565b5f5f6040838503121561126c5761126b610d6d565b5b5f61127985828601610e7e565b925050602061128a85828601610e7e565b9150509250929050565b5f819050919050565b5f6112b76112b26112ad84610e38565b611294565b610e38565b9050919050565b5f6112c88261129d565b9050919050565b5f6112d9826112be565b9050919050565b6112e9816112cf565b82525050565b5f6020820190506113025f8301846112e0565b92915050565b5f611312826112be565b9050919050565b61132281611308565b82525050565b5f60208201905061133b5f830184611319565b92915050565b5f5f6040838503121561135757611356610d6d565b5b5f61136485828601610eee565b925050602061137585828601610eee565b9150509250929050565b61138881610d75565b82525050565b5f6020820190506113a15f83018461137f565b92915050565b5f5f5f606084860312156113be576113bd610d6d565b5b5f6113cb86828701610d94565b93505060206113dc86828701610d94565b92505060406113ed86828701610e7e565b9150509250925092565b5f60608201905061140a5f83018661112c565b818103602083015261141c8185611163565b905061142b604083018461137f565b949350505050565b5f6020828403121561144857611447610d6d565b5b5f82013567ffffffffffffffff81111561146557611464610d71565b5b61147184828501610f89565b91505092915050565b5f6020820190508181035f8301526114928184611163565b905092915050565b6114a381610e57565b82525050565b6114b281610e92565b82525050565b6114c181610d75565b82525050565b6114d081610ecf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6114fa826114d6565b61150481856114e0565b9350611514818560208601611155565b61151d81610dac565b840191505092915050565b5f61010083015f83015161153e5f86018261149a565b50602083015161155160208601826114a9565b506040830151611564604086018261149a565b50606083015161157760608601826114b8565b50608083015161158a608086018261149a565b5060a083015161159d60a08601826114c7565b5060c083015184820360c08601526115b582826114f0565b91505060e083015184820360e08601526115cf82826114f0565b9150508091505092915050565b5f6040820190508181035f8301526115f48185611528565b9050611603602083018461137f565b9392505050565b61161381611121565b811461161d575f5ffd5b50565b5f8151905061162e8161160a565b92915050565b5f6020828403121561164957611648610d6d565b5b5f61165684828501611620565b91505092915050565b5f8160e01c9050919050565b5f60033d11156116875760045f5f3e6116845f5161165f565b90505b90565b5f60443d106117165761169b610d64565b60043d036004823e80513d602482011167ffffffffffffffff821117156116c3575050611716565b808201805167ffffffffffffffff8111156116e15750505050611716565b80602083010160043d0385018111156116fe575050505050611716565b61170d82602001850186610de9565b82955050505050505b90565b5f5f60233d111561173357602060045f3e600191505f5190505b9091565b5f8151905061174581610d7e565b92915050565b5f602082840312156117605761175f610d6d565b5b5f61176d84828501611737565b91505092915050565b61177f81610e57565b82525050565b5f6040820190506117985f83018561137f565b6117a56020830184611776565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f6117f182516117bb565b80915050919050565b5f82821b905092915050565b5f611810826114d6565b8261181a846117ac565b9050611825816117e6565b92506004821015611865576118607fffffffff00000000000000000000000000000000000000000000000000000000836004036008026117fa565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220654d6bab26b804b5d941c0140eea91e488571d0925c255a2dd894a9677f0ce9564736f6c634300081c0033', + '0x608060405234801561000f575f5ffd5b50600436106100a7575f3560e01c80637e0f4b5b1161006f5780637e0f4b5b146101655780638a5c8c7f14610183578063a02eb534146101b3578063a0639f54146101e5578063d73a365f14610217578063ff6957d314610249576100a7565b806309ba3156146100ab5780631a1992a9146100dd578063267c4ae41461010d578063485cc9551461012b5780634cdc014d14610147575b5f5ffd5b6100c560048036038101906100c09190611538565b610279565b6040516100d49392919061162d565b60405180910390f35b6100f760048036038101906100f29190611669565b61055c565b60405161010491906116a7565b60405180910390f35b61011561056a565b60405161012291906116c0565b60405180910390f35b610145600480360381019061014091906116d9565b610572565b005b61014f6105f5565b60405161015c9190611772565b60405180910390f35b61016d61061a565b60405161017a91906117ab565b60405180910390f35b61019d600480360381019061019891906117c4565b61063e565b6040516101aa9190611811565b60405180910390f35b6101cd60048036038101906101c8919061182a565b61064c565b6040516101dc9392919061187a565b60405180910390f35b6101ff60048036038101906101fa9190611538565b6108db565b60405161020e9392919061187a565b60405180910390f35b610231600480360381019061022c91906118b6565b610b65565b6040516102409392919061187a565b60405180910390f35b610263600480360381019061025e9190611910565b610fab565b6040516102709190611957565b60405180910390f35b5f60605f5f5f1b8460a00151036102bc576040517fb78926d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b8152600401610319929190611ab9565b602060405180830381865afa92505050801561035357506040513d601f19601f820116820180604052508101906103509190611b11565b60015b61043f5761035f611b48565b806308c379a0036103905750610373611b67565b8061037e57506103f5565b5f815f5f1b9450945094505050610553565b634e487b71036103f5576103a2611bf6565b906103ad57506103f5565b5f5f5f1b6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610553565b3d805f811461041f576040519150601f19603f3d011682016040523d82523d5f602084013e610424565b606091505b505f61042f82610fab565b5f5f1b9450945094505050610553565b809150508061048f575f5f5f1b6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610553565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016104e99190611811565b602060405180830381865afa158015610504573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105289190611c28565b9050600161053a828860a0015161055c565b60405180602001604052805f8152509094509450945050505b93509350939050565b5f81835f1b18905092915050565b5f6001905090565b815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8183185f1c905092915050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635faa299a88876040518363ffffffff1660e01b81526004016106ad929190611c62565b602060405180830381865afa9250505080156106e757506040513d601f19601f820116820180604052508101906106e49190611b11565b60015b6107cd576106f3611b48565b806308c379a0036107225750610707611b67565b806107125750610785565b5f815f94509450945050506108d2565b634e487b710361078557610734611bf6565b9061073f5750610785565b5f5f6040518060400160405280600581526020017f50616e69630000000000000000000000000000000000000000000000000000008152509094509450945050506108d2565b3d805f81146107af576040519150601f19603f3d011682016040523d82523d5f602084013e6107b4565b606091505b505f6107bf82610fab565b5f94509450945050506108d2565b809150508061081b575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f7765640000000000000000000000000000000000000000000081525090935093509350506108d2565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b81526004016108759190611811565b602060405180830381865afa158015610890573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b49190611c28565b905060018160405180602001604052805f8152509094509450945050505b93509350939050565b5f60605f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86896040518363ffffffff1660e01b815260040161093c929190611ab9565b602060405180830381865afa92505050801561097657506040513d601f19601f820116820180604052508101906109739190611b11565b60015b610a5c57610982611b48565b806308c379a0036109b15750610996611b67565b806109a15750610a14565b5f815f9450945094505050610b5c565b634e487b7103610a14576109c3611bf6565b906109ce5750610a14565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610b5c565b3d805f8114610a3e576040519150601f19603f3d011682016040523d82523d5f602084013e610a43565b606091505b505f610a4e82610fab565b5f9450945094505050610b5c565b8091505080610aaa575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610b5c565b60015f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b896040518263ffffffff1660e01b8152600401610b059190611811565b602060405180830381865afa158015610b20573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b449190611c28565b60405180602001604052805f81525090935093509350505b93509350939050565b5f60605f5f5f73ffffffffffffffffffffffffffffffffffffffff16855f015173ffffffffffffffffffffffffffffffffffffffff1614610d24575f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ae79f04a86886040518363ffffffff1660e01b8152600401610bfb929190611ab9565b602060405180830381865afa925050508015610c3557506040513d601f19601f82011682018060405250810190610c329190611b11565b60015b610d1b57610c41611b48565b806308c379a003610c705750610c55611b67565b80610c605750610cd3565b5f815f9450945094505050610fa4565b634e487b7103610cd357610c82611bf6565b90610c8d5750610cd3565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610fa4565b3d805f8114610cfd576040519150601f19603f3d011682016040523d82523d5f602084013e610d02565b606091505b505f610d0d82610fab565b5f9450945094505050610fa4565b80915050610ea3565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166394d9184c876040518263ffffffff1660e01b8152600401610d7e9190611811565b602060405180830381865afa925050508015610db857506040513d601f19601f82011682018060405250810190610db59190611b11565b60015b610e9e57610dc4611b48565b806308c379a003610df35750610dd8611b67565b80610de35750610e56565b5f815f9450945094505050610fa4565b634e487b7103610e5657610e05611bf6565b90610e105750610e56565b5f5f6040518060400160405280600581526020017f50616e6963000000000000000000000000000000000000000000000000000000815250909450945094505050610fa4565b3d805f8114610e80576040519150601f19603f3d011682016040523d82523d5f602084013e610e85565b606091505b505f610e9082610fab565b5f9450945094505050610fa4565b809150505b80610eed575f5f6040518060400160405280600a81526020017f4e6f74416c6c6f776564000000000000000000000000000000000000000000008152509093509350935050610fa4565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c76642b886040518263ffffffff1660e01b8152600401610f479190611811565b602060405180830381865afa158015610f62573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f869190611c28565b905060018160405180602001604052805f8152509094509450945050505b9250925092565b60605f82610fb890611ce3565b905063ed0764a160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611044576040518060400160405280601981526020017f5065726d697373696f6e496e76616c69645f45787069726564000000000000008152509150506111e2565b634c40eccb60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036110b157604051806060016040528060218152602001611d6e602191399150506111e2565b638e143bf760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361111e57604051806060016040528060248152602001611d4a602491399150506111e2565b63cbd3a96660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036111a8576040518060400160405280601a81526020017f5065726d697373696f6e496e76616c69645f44697361626c65640000000000008152509150506111e2565b6040518060400160405280600f81526020017f4c6f77204c6576656c204572726f7200000000000000000000000000000000008152509150505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61120a816111f8565b8114611214575f5ffd5b50565b5f8135905061122581611201565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6112758261122f565b810181811067ffffffffffffffff821117156112945761129361123f565b5b80604052505050565b5f6112a66111e7565b90506112b2828261126c565b919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6112e4826112bb565b9050919050565b6112f4816112da565b81146112fe575f5ffd5b50565b5f8135905061130f816112eb565b92915050565b5f67ffffffffffffffff82169050919050565b61133181611315565b811461133b575f5ffd5b50565b5f8135905061134c81611328565b92915050565b5f819050919050565b61136481611352565b811461136e575f5ffd5b50565b5f8135905061137f8161135b565b92915050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156113a7576113a661123f565b5b6113b08261122f565b9050602081019050919050565b828183375f83830152505050565b5f6113dd6113d88461138d565b61129d565b9050828152602081018484840111156113f9576113f8611389565b5b6114048482856113bd565b509392505050565b5f82601f8301126114205761141f611385565b5b81356114308482602086016113cb565b91505092915050565b5f610100828403121561144f5761144e61122b565b5b61145a61010061129d565b90505f61146984828501611301565b5f83015250602061147c8482850161133e565b602083015250604061149084828501611301565b60408301525060606114a484828501611217565b60608301525060806114b884828501611301565b60808301525060a06114cc84828501611371565b60a08301525060c082013567ffffffffffffffff8111156114f0576114ef6112b7565b5b6114fc8482850161140c565b60c08301525060e082013567ffffffffffffffff8111156115205761151f6112b7565b5b61152c8482850161140c565b60e08301525092915050565b5f5f5f6060848603121561154f5761154e6111f0565b5b5f61155c86828701611217565b935050602061156d86828701611217565b925050604084013567ffffffffffffffff81111561158e5761158d6111f4565b5b61159a86828701611439565b9150509250925092565b5f8115159050919050565b6115b8816115a4565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6115f0826115be565b6115fa81856115c8565b935061160a8185602086016115d8565b6116138161122f565b840191505092915050565b61162781611352565b82525050565b5f6060820190506116405f8301866115af565b818103602083015261165281856115e6565b9050611661604083018461161e565b949350505050565b5f5f6040838503121561167f5761167e6111f0565b5b5f61168c85828601611217565b925050602061169d85828601611371565b9150509250929050565b5f6020820190506116ba5f83018461161e565b92915050565b5f6020820190506116d35f8301846115af565b92915050565b5f5f604083850312156116ef576116ee6111f0565b5b5f6116fc85828601611301565b925050602061170d85828601611301565b9150509250929050565b5f819050919050565b5f61173a611735611730846112bb565b611717565b6112bb565b9050919050565b5f61174b82611720565b9050919050565b5f61175c82611741565b9050919050565b61176c81611752565b82525050565b5f6020820190506117855f830184611763565b92915050565b5f61179582611741565b9050919050565b6117a58161178b565b82525050565b5f6020820190506117be5f83018461179c565b92915050565b5f5f604083850312156117da576117d96111f0565b5b5f6117e785828601611371565b92505060206117f885828601611371565b9150509250929050565b61180b816111f8565b82525050565b5f6020820190506118245f830184611802565b92915050565b5f5f5f60608486031215611841576118406111f0565b5b5f61184e86828701611217565b935050602061185f86828701611217565b925050604061187086828701611301565b9150509250925092565b5f60608201905061188d5f8301866115af565b818103602083015261189f81856115e6565b90506118ae6040830184611802565b949350505050565b5f5f604083850312156118cc576118cb6111f0565b5b5f6118d985828601611217565b925050602083013567ffffffffffffffff8111156118fa576118f96111f4565b5b61190685828601611439565b9150509250929050565b5f60208284031215611925576119246111f0565b5b5f82013567ffffffffffffffff811115611942576119416111f4565b5b61194e8482850161140c565b91505092915050565b5f6020820190508181035f83015261196f81846115e6565b905092915050565b611980816112da565b82525050565b61198f81611315565b82525050565b61199e816111f8565b82525050565b6119ad81611352565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6119d7826119b3565b6119e181856119bd565b93506119f18185602086016115d8565b6119fa8161122f565b840191505092915050565b5f61010083015f830151611a1b5f860182611977565b506020830151611a2e6020860182611986565b506040830151611a416040860182611977565b506060830151611a546060860182611995565b506080830151611a676080860182611977565b5060a0830151611a7a60a08601826119a4565b5060c083015184820360c0860152611a9282826119cd565b91505060e083015184820360e0860152611aac82826119cd565b9150508091505092915050565b5f6040820190508181035f830152611ad18185611a05565b9050611ae06020830184611802565b9392505050565b611af0816115a4565b8114611afa575f5ffd5b50565b5f81519050611b0b81611ae7565b92915050565b5f60208284031215611b2657611b256111f0565b5b5f611b3384828501611afd565b91505092915050565b5f8160e01c9050919050565b5f60033d1115611b645760045f5f3e611b615f51611b3c565b90505b90565b5f60443d10611bf357611b786111e7565b60043d036004823e80513d602482011167ffffffffffffffff82111715611ba0575050611bf3565b808201805167ffffffffffffffff811115611bbe5750505050611bf3565b80602083010160043d038501811115611bdb575050505050611bf3565b611bea8260200185018661126c565b82955050505050505b90565b5f5f60233d1115611c1057602060045f3e600191505f5190505b9091565b5f81519050611c2281611201565b92915050565b5f60208284031215611c3d57611c3c6111f0565b5b5f611c4a84828501611c14565b91505092915050565b611c5c816112da565b82525050565b5f604082019050611c755f830185611802565b611c826020830184611c53565b9392505050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f611cce8251611c98565b80915050919050565b5f82821b905092915050565b5f611ced826119b3565b82611cf784611c89565b9050611d0281611cc3565b92506004821015611d4257611d3d7fffffffff0000000000000000000000000000000000000000000000000000000083600403600802611cd7565b831692505b505091905056fe5065726d697373696f6e496e76616c69645f526563697069656e745369676e61747572655065726d697373696f6e496e76616c69645f4973737565725369676e6174757265a2646970667358221220aa4dc2507b0bdb7f5260c522fbce85df9c06aaa13facf4056933f01ea3c2d42264736f6c634300081c0033', } satisfies MockArtifact; diff --git a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts new file mode 100644 index 00000000..a72e1632 --- /dev/null +++ b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts @@ -0,0 +1,65 @@ +import { type Permit, PermitUtils } from '@/permits'; + +import { type PublicClient } from 'viem'; +import { sleep } from '../utils.js'; +import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js'; +import { FheTypes } from '../types.js'; +import { CofheError, CofheErrorCode } from '../error.js'; +import { MOCKS_QUERY_DECRYPTER_ADDRESS } from '../consts.js'; + +export async function cofheMocksDecryptForTx( + ctHash: bigint, + utype: FheTypes, + permit: Permit | null, + publicClient: PublicClient, + mocksDecryptForTxDelay: number +): Promise { + // Configurable delay before decrypting to simulate the CoFHE decrypt processing time + // Recommended 1000ms on web + // Recommended 0ms on hardhat (will be called during tests no need for fake delay) + if (mocksDecryptForTxDelay > 0) await sleep(mocksDecryptForTxDelay); + + // Prepare permission object - null/empty permit means no permission (global allowance check) + let permission: any; + if (permit !== null) { + permission = PermitUtils.getPermission(permit, true); + permission = { + ...permission, + expiration: BigInt(permission.expiration), + validatorId: BigInt(permission.validatorId), + }; + } else { + // Empty permission with zero issuer for global allowance check + permission = { + issuer: '0x0000000000000000000000000000000000000000' as const, + sealingKey: 0n, + expiration: 0n, + validatorId: 0n, + signature: '0x' as const, + }; + } + + const [allowed, error, result] = await publicClient.readContract({ + address: MOCKS_QUERY_DECRYPTER_ADDRESS, + abi: MockThresholdNetworkAbi, + functionName: 'decryptForTx', + args: [ctHash, permission], + }); + + if (error != '') { + throw new CofheError({ + code: CofheErrorCode.DecryptFailed, + message: `mocks decryptForTx call failed: ${error}`, + }); + } + + if (allowed == false) { + throw new CofheError({ + code: CofheErrorCode.DecryptFailed, + message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`, + }); + } + + // decryptForTx returns plaintext directly (no sealing/unsealing needed) + return BigInt(result); +} diff --git a/packages/sdk/core/decrypt/decryptHandleBuilder.ts b/packages/sdk/core/decrypt/decryptHandleBuilder.ts index d6600d12..10858869 100644 --- a/packages/sdk/core/decrypt/decryptHandleBuilder.ts +++ b/packages/sdk/core/decrypt/decryptHandleBuilder.ts @@ -10,6 +10,7 @@ import { BaseBuilder, type BaseBuilderParams } from '../baseBuilder.js'; import { cofheMocksSealOutput } from './cofheMocksSealOutput.js'; // import { tnSealOutputV1 } from './tnSealOutputV1.js'; import { tnSealOutputV2 } from './tnSealOutputV2.js'; +import { cofheMocksDecryptForTx } from './cofheMocksDecryptForTx.js'; /** * API @@ -217,6 +218,14 @@ export class DecryptHandlesBuilder extends BaseBuilder { return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay); } + // private async mocksDecryptForTx(permit: Permit): Promise { + // this.assertPublicClient(); + + // // TODO: delay - should be separate config setting? + // const delay = this.config.mocks.sealOutputDelay; + // return cofheMocksDecryptForTx(this.ctHash, this.utype, permit, this.publicClient, delay); + // } + /** * In the production context, perform a true decryption with the CoFHE coprocessor. */ From 9b3172b2c2310933090dbe610816b112b63ef098 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 16:08:24 +0200 Subject: [PATCH 17/24] feat: add DecryptForTxBuilder and decryptForTx client bindings (mock only for now) --- packages/sdk/core/client.ts | 18 + packages/sdk/core/clientTypes.ts | 2 + .../sdk/core/decrypt/decryptForTxBuilder.ts | 314 ++++++++++++++++++ packages/sdk/core/index.ts | 2 + 4 files changed, 336 insertions(+) create mode 100644 packages/sdk/core/decrypt/decryptForTxBuilder.ts diff --git a/packages/sdk/core/client.ts b/packages/sdk/core/client.ts index 8fcf3846..5e54b878 100644 --- a/packages/sdk/core/client.ts +++ b/packages/sdk/core/client.ts @@ -7,6 +7,7 @@ import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; import { createKeysStore } from './keyStore.js'; import { permits } from './permits.js'; import { DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +import { DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; import { getPublicClientChainID, getWalletClientAccount } from './utils.js'; import type { CofheClientConnectionState, CofheClientParams, CofheClient, CofheClientPermits } from './clientTypes.js'; import type { EncryptableItem, FheTypes } from './types.js'; @@ -162,6 +163,22 @@ export function createCofheClientBase( }); } + function decryptForTx(ctHash: bigint): DecryptForTxBuilder { + const state = connectStore.getState(); + + return new DecryptForTxBuilder({ + ctHash, + chainId: state.chainId ?? undefined, + account: state.account ?? undefined, + + config: opts.config, + publicClient: state.publicClient ?? undefined, + walletClient: state.walletClient ?? undefined, + + requireConnected: _requireConnected, + }); + } + // PERMITS - Context-aware wrapper const _getChainIdAndAccount = (chainId?: number, account?: string) => { @@ -298,6 +315,7 @@ export function createCofheClientBase( disconnect, encryptInputs, decryptHandle, + decryptForTx, permits: clientPermits, // Add SDK-specific methods below that require connection diff --git a/packages/sdk/core/clientTypes.ts b/packages/sdk/core/clientTypes.ts index 97d9ef50..3a90e616 100644 --- a/packages/sdk/core/clientTypes.ts +++ b/packages/sdk/core/clientTypes.ts @@ -2,6 +2,7 @@ import { type PublicClient, type WalletClient } from 'viem'; import { type CofheConfig } from './config.js'; import { type DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +import { type DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; import { type EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; import { type ZkBuilderAndCrsGenerator, type ZkProveWorkerFunction } from './encrypt/zkPackProveVerify.js'; import { type FheKeyDeserializer } from './fetchKeys.js'; @@ -45,6 +46,7 @@ export type CofheClient = { */ encryptInputs(inputs: [...T]): EncryptInputsBuilder<[...T]>; decryptHandle(ctHash: bigint, utype: U): DecryptHandlesBuilder; + decryptForTx(ctHash: bigint): DecryptForTxBuilder; permits: CofheClientPermits; }; diff --git a/packages/sdk/core/decrypt/decryptForTxBuilder.ts b/packages/sdk/core/decrypt/decryptForTxBuilder.ts new file mode 100644 index 00000000..cb902de0 --- /dev/null +++ b/packages/sdk/core/decrypt/decryptForTxBuilder.ts @@ -0,0 +1,314 @@ +import { hardhat } from '@/chains'; +import { type Permit, PermitUtils } from '@/permits'; + +import { FheTypes } from '../types.js'; +import { getThresholdNetworkUrlOrThrow } from '../config.js'; +import { CofheError, CofheErrorCode } from '../error.js'; +import { permits } from '../permits.js'; +import { BaseBuilder, type BaseBuilderParams } from '../baseBuilder.js'; +import { cofheMocksDecryptForTx } from './cofheMocksDecryptForTx.js'; +// TODO: import { tnDecryptForTxV1 } from './tnDecryptForTxV1.js'; + +/** + * API + * + * await client.decryptForTx(ctHash) + * .setChainId(chainId) + * .setAccount(account) + * .withPermit(permit | permitHash | undefined) + * .execute() + * + * If chainId not set, uses client's chainId + * If account not set, uses client's account + * If withPermit not called, uses active permit from chainId + account + * If withPermit(undefined/null), uses global allowance (no permit required) + * + * Returns the decrypted value + proof ready for tx. + */ + +type DecryptForTxBuilderParams = BaseBuilderParams & { + ctHash: bigint; + permitHash?: string; + permit?: Permit | null; +}; + +export type DecryptForTxResult = { + decryptedValue: bigint; + proof: string; // TODO: actual proof structure when available +}; + +export class DecryptForTxBuilder extends BaseBuilder { + private ctHash: bigint; + private permitHash?: string; + private permit?: Permit | null; + private permitSet = false; // Track if withPermit was explicitly called + + constructor(params: DecryptForTxBuilderParams) { + super({ + config: params.config, + publicClient: params.publicClient, + walletClient: params.walletClient, + chainId: params.chainId, + account: params.account, + requireConnected: params.requireConnected, + }); + + this.ctHash = params.ctHash; + this.permitHash = params.permitHash; + this.permit = params.permit; + } + + /** + * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit. + * + * If not provided, the chainId will be fetched from the connected publicClient. + * + * Example: + * ```typescript + * const result = await decryptForTx(ctHash) + * .setChainId(11155111) + * .execute(); + * ``` + * + * @returns The chainable DecryptForTxBuilder instance. + */ + setChainId(chainId: number): DecryptForTxBuilder { + this.chainId = chainId; + return this; + } + + getChainId(): number | undefined { + return this.chainId; + } + + /** + * @param account - Account to decrypt values from. Used to fetch the correct permit. + * + * If not provided, the account will be fetched from the connected walletClient. + * + * Example: + * ```typescript + * const result = await decryptForTx(ctHash) + * .setAccount('0x1234567890123456789012345678901234567890') + * .execute(); + * ``` + * + * @returns The chainable DecryptForTxBuilder instance. + */ + setAccount(account: string): DecryptForTxBuilder { + this.account = account; + return this; + } + + getAccount(): string | undefined { + return this.account; + } + + /** + * @param permitHashOrPermitOrUndefined - Permit hash to fetch, Permit object to use directly, or undefined for global allowance. + * + * If a string is provided, it's treated as a permit hash and will be fetched. + * If a Permit object is provided, it will be used directly. + * If undefined/null is provided, uses global allowance (no permit required). + * If not called, fetches the active permit for the chainId + account. + * + * Example with permit hash: + * ```typescript + * const result = await decryptForTx(ctHash) + * .withPermit('0x1234567890123456789012345678901234567890') + * .execute(); + * ``` + * + * Example with permit object: + * ```typescript + * const result = await decryptForTx(ctHash) + * .withPermit(permit) + * .execute(); + * ``` + * + * Example with global allowance (no permit): + * ```typescript + * const result = await decryptForTx(ctHash) + * .withPermit(undefined) + * .execute(); + * ``` + * + * @returns The chainable DecryptForTxBuilder instance. + */ + withPermit(permitHashOrPermitOrUndefined: string | Permit | undefined | null): DecryptForTxBuilder { + this.permitSet = true; + + if (typeof permitHashOrPermitOrUndefined === 'string') { + this.permitHash = permitHashOrPermitOrUndefined; + this.permit = undefined; + } else if (permitHashOrPermitOrUndefined === undefined || permitHashOrPermitOrUndefined === null) { + // Global allowance - no permit required + this.permit = null; + this.permitHash = undefined; + } else { + // Permit object + this.permit = permitHashOrPermitOrUndefined; + this.permitHash = undefined; + } + + return this; + } + + getPermit(): Permit | null | undefined { + return this.permit; + } + + getPermitHash(): string | undefined { + return this.permitHash; + } + + private async getThresholdNetworkUrl(): Promise { + this.assertChainId(); + return getThresholdNetworkUrlOrThrow(this.config, this.chainId); + } + + private async getResolvedPermit(): Promise { + // If permit was explicitly set via withPermit() + if (this.permitSet) { + return this.permit ?? null; + } + + // If permit object directly provided + if (this.permit) return this.permit; + + this.assertChainId(); + this.assertAccount(); + + // Fetch with permit hash + if (this.permitHash) { + const permit = await permits.getPermit(this.chainId, this.account, this.permitHash); + if (!permit) { + throw new CofheError({ + code: CofheErrorCode.PermitNotFound, + message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`, + hint: 'Ensure the permit exists and is valid.', + context: { + chainId: this.chainId, + account: this.account, + permitHash: this.permitHash, + }, + }); + } + return permit; + } + + // Fetch with active permit + const permit = await permits.getActivePermit(this.chainId, this.account); + if (!permit) { + throw new CofheError({ + code: CofheErrorCode.PermitNotFound, + message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`, + hint: 'Ensure a permit exists for this account on this chain.', + context: { + chainId: this.chainId, + account: this.account, + }, + }); + } + return permit; + } + + /** + * On hardhat, interact with MockThresholdNetwork contract + */ + private async mocksDecryptForTx(permit: Permit | null): Promise { + this.assertPublicClient(); + + const delay = this.config.mocks.sealOutputDelay; + return cofheMocksDecryptForTx(this.ctHash, 0 as FheTypes, permit, this.publicClient, delay); + } + + /** + * In the production context, perform a true decryption with the CoFHE coprocessor. + */ + private async productionDecryptForTx(permit: Permit | null): Promise { + this.assertChainId(); + this.assertPublicClient(); + + const thresholdNetworkUrl = await this.getThresholdNetworkUrl(); + // TODO: implement tnDecryptForTxV1 + // const result = await tnDecryptForTxV1(this.ctHash, this.chainId, permit, thresholdNetworkUrl); + throw new CofheError({ + code: CofheErrorCode.InternalError, + message: 'Production decryptForTx not yet implemented', + hint: 'Use mocks or wait for production implementation.', + }); + } + + /** + * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN. + * + * This will: + * - Use a permit based on: + * - withPermit(permit) if provided + * - withPermit(permitHash) to fetch permit + * - withPermit(undefined) for global allowance (no permit) + * - or active permit for chainId + account + * - Call CoFHE `/decryptForTx` with the permit or empty permit for global allowance + * - Return the decrypted value + proof ready for transaction + * + * Example: + * ```typescript + * // With permit + * const result = await client.decryptForTx(ctHash) + * .setChainId(11155111) + * .setAccount('0x123...890') + * .execute(); + * + * // With global allowance + * const result = await client.decryptForTx(ctHash) + * .withPermit(undefined) + * .execute(); + * ``` + * + * @returns Object containing decrypted value and proof ready for tx. + */ + async execute(): Promise { + // Resolve permit (can be Permit object or null for global allowance) + const permit = await this.getResolvedPermit(); + + // If permit is provided, validate it + if (permit !== null) { + // Ensure permit validity + PermitUtils.validate(permit); + PermitUtils.isValid(permit); + + // Extract chainId from signed permit + const chainId = permit._signedDomain!.chainId; + + let decryptedValue: bigint; + + if (chainId === hardhat.id) { + decryptedValue = await this.mocksDecryptForTx(permit); + } else { + decryptedValue = await this.productionDecryptForTx(permit); + } + + return { + decryptedValue, + proof: '', // TODO: actual proof structure when available + }; + } else { + // Global allowance - no permit + this.assertChainId(); + + let decryptedValue: bigint; + + if (this.chainId === hardhat.id) { + decryptedValue = await this.mocksDecryptForTx(null); + } else { + decryptedValue = await this.productionDecryptForTx(null); + } + + return { + decryptedValue, + proof: '', // TODO: actual proof structure when available + }; + } + } +} diff --git a/packages/sdk/core/index.ts b/packages/sdk/core/index.ts index 22b0ff38..99942b91 100644 --- a/packages/sdk/core/index.ts +++ b/packages/sdk/core/index.ts @@ -73,6 +73,8 @@ export type { KeysStorage, KeysStore } from './keyStore.js'; // Builders (exported via client, but can be imported directly for typing) export { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; export { DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +export { DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; +export type { DecryptForTxResult } from './decrypt/decryptForTxBuilder.js'; // ZK utilities export type { From cd6f03fc24deb6677c53d9bf6dc0afdbd533a469 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 16:52:29 +0200 Subject: [PATCH 18/24] tests: client.decryptForTx mocks --- .../test/decrypt-for-tx.test.ts | 160 ++++++++++++++++++ .../core/decrypt/MockThresholdNetworkAbi.ts | 28 +++ .../core/decrypt/cofheMocksDecryptForTx.ts | 27 ++- .../sdk/core/decrypt/decryptForTxBuilder.ts | 39 ++--- 4 files changed, 227 insertions(+), 27 deletions(-) create mode 100644 packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts diff --git a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts new file mode 100644 index 00000000..1499c4a0 --- /dev/null +++ b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts @@ -0,0 +1,160 @@ +import hre from 'hardhat'; +import { CofheClient, Encryptable, FheTypes } from '@cofhe/sdk'; +import { TASK_COFHE_MOCKS_DEPLOY } from './consts'; +import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import { PermitUtils } from '@cofhe/sdk/permits'; + +describe('DecryptForTx Integration Tests', () => { + let cofheClient: CofheClient; + let testContract: any; + let signer: HardhatEthersSigner; + + before(async function () { + await hre.run(TASK_COFHE_MOCKS_DEPLOY); + const [tmpSigner] = await hre.ethers.getSigners(); + signer = tmpSigner; + cofheClient = await hre.cofhe.createClientWithBatteries(signer); + + const SimpleTest = await hre.ethers.getContractFactory('SimpleTest'); + testContract = await SimpleTest.deploy(); + await testContract.waitForDeployment(); + console.log(`Test contract deployed at: ${await testContract.getAddress()}`); + }); + + describe('decryptForTx with global allowance', () => { + it('Should decrypt a value without a permit', async function () { + const testValue = 42n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); + + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + }); + + it('Should decrypt different values consistently', async function () { + const testValues = [1n, 100n, 1000n, 65535n]; + + for (const testValue of testValues) { + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + } + }); + }); + + describe('decryptForTx with permit', () => { + it('Should decrypt with a self permit', async function () { + const testValue = 99n; + const permit = await cofheClient.permits.createSelf({ + issuer: signer.address, + name: 'Test Permit', + }); + + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).withPermit(permit).execute(); + + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + }); + + it('Should auto-resolve active permit', async function () { + const testValue = 88n; + const permit = await cofheClient.permits.createSelf({ + issuer: signer.address, + name: 'Active Test Permit', + }); + const permitHash = PermitUtils.getHash(permit); + cofheClient.permits.selectActivePermit(permitHash); + + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); + + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + }); + }); + + describe('decryptForTx builder chain', () => { + it('Should support builder chaining', async function () { + const testValue = 33n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).setAccount(signer.address).execute(); + + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + }); + + it('Should maintain builder state across multiple calls', async function () { + const testValue = 22n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const builder = cofheClient.decryptForTx(encrypted[0].ctHash).setAccount(signer.address); + + const result1 = await builder.execute(); + expect(result1.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result1.decryptedValue).to.be.equal(testValue); + + const result2 = await builder.execute(); + expect(result2.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result2.decryptedValue).to.be.equal(testValue); + }); + }); + + describe('decryptForTx error cases', () => { + // Error handling tests - can be extended as needed + }); + + describe('decryptForTx vs decryptHandle', () => { + it('Should return plaintext value', async function () { + const testValue = 123n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const decryptForTxResult = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); + + expect(decryptForTxResult.ctHash).to.be.equal(encrypted[0].ctHash); + expect(decryptForTxResult.decryptedValue).to.be.equal(testValue); + expect(typeof decryptForTxResult.signature).to.equal('string'); + }); + + it('Should support both decryptHandle and decryptForTx', async function () { + const testValue = 234n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setValue(encrypted[0]); + await tx.wait(); + + const ctHash = encrypted[0].ctHash; + const handleResult = await cofheClient.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const forTxResult = await cofheClient.decryptForTx(ctHash).execute(); + + expect(handleResult).to.be.equal(testValue); + expect(forTxResult.ctHash).to.be.equal(ctHash); + expect(forTxResult.decryptedValue).to.be.equal(testValue); + }); + }); +}); diff --git a/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts b/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts index 13eb8bdc..765c262a 100644 --- a/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts +++ b/packages/sdk/core/decrypt/MockThresholdNetworkAbi.ts @@ -137,4 +137,32 @@ export const MockThresholdNetworkAbi = [ ], stateMutability: 'view', }, + { + type: 'function', + name: 'decryptForTx', + inputs: [ + { name: 'ctHash', type: 'uint256', internalType: 'uint256' }, + { + name: 'permission', + type: 'tuple', + internalType: 'struct Permission', + components: [ + { name: 'issuer', type: 'address', internalType: 'address' }, + { name: 'expiration', type: 'uint64', internalType: 'uint64' }, + { name: 'recipient', type: 'address', internalType: 'address' }, + { name: 'validatorId', type: 'uint256', internalType: 'uint256' }, + { name: 'validatorContract', type: 'address', internalType: 'address' }, + { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' }, + { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' }, + { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' }, + ], + }, + ], + outputs: [ + { name: 'allowed', type: 'bool', internalType: 'bool' }, + { name: 'error', type: 'string', internalType: 'string' }, + { name: 'decryptedValue', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'view', + }, ] as const; diff --git a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts index a72e1632..3bf4f42e 100644 --- a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts +++ b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts @@ -7,13 +7,19 @@ import { FheTypes } from '../types.js'; import { CofheError, CofheErrorCode } from '../error.js'; import { MOCKS_QUERY_DECRYPTER_ADDRESS } from '../consts.js'; +export type DecryptForTxMocksResult = { + ctHash: bigint; + decryptedValue: bigint; + signature: string; +}; + export async function cofheMocksDecryptForTx( ctHash: bigint, utype: FheTypes, permit: Permit | null, publicClient: PublicClient, mocksDecryptForTxDelay: number -): Promise { +): Promise { // Configurable delay before decrypting to simulate the CoFHE decrypt processing time // Recommended 1000ms on web // Recommended 0ms on hardhat (will be called during tests no need for fake delay) @@ -30,12 +36,16 @@ export async function cofheMocksDecryptForTx( }; } else { // Empty permission with zero issuer for global allowance check + // Must include all fields that the Permission struct requires permission = { - issuer: '0x0000000000000000000000000000000000000000' as const, - sealingKey: 0n, + issuer: '0x0000000000000000000000000000000000000000', expiration: 0n, + recipient: '0x0000000000000000000000000000000000000000', validatorId: 0n, - signature: '0x' as const, + validatorContract: '0x0000000000000000000000000000000000000000', + sealingKey: '0x0000000000000000000000000000000000000000000000000000000000000000', + issuerSignature: '0x', + recipientSignature: '0x', }; } @@ -61,5 +71,12 @@ export async function cofheMocksDecryptForTx( } // decryptForTx returns plaintext directly (no sealing/unsealing needed) - return BigInt(result); + // Generate a mock threshold network signature (in production, this would be the actual signature) + const signature = `0x${ctHash.toString(16).padStart(64, '0')}`; + + return { + ctHash, + decryptedValue: BigInt(result), + signature, + }; } diff --git a/packages/sdk/core/decrypt/decryptForTxBuilder.ts b/packages/sdk/core/decrypt/decryptForTxBuilder.ts index cb902de0..af029399 100644 --- a/packages/sdk/core/decrypt/decryptForTxBuilder.ts +++ b/packages/sdk/core/decrypt/decryptForTxBuilder.ts @@ -7,6 +7,7 @@ import { CofheError, CofheErrorCode } from '../error.js'; import { permits } from '../permits.js'; import { BaseBuilder, type BaseBuilderParams } from '../baseBuilder.js'; import { cofheMocksDecryptForTx } from './cofheMocksDecryptForTx.js'; +import { getPublicClientChainID } from '../utils.js'; // TODO: import { tnDecryptForTxV1 } from './tnDecryptForTxV1.js'; /** @@ -33,8 +34,9 @@ type DecryptForTxBuilderParams = BaseBuilderParams & { }; export type DecryptForTxResult = { + ctHash: bigint; decryptedValue: bigint; - proof: string; // TODO: actual proof structure when available + signature: string; // Threshold network signature for publishDecryptResult }; export class DecryptForTxBuilder extends BaseBuilder { @@ -216,17 +218,18 @@ export class DecryptForTxBuilder extends BaseBuilder { /** * On hardhat, interact with MockThresholdNetwork contract */ - private async mocksDecryptForTx(permit: Permit | null): Promise { + private async mocksDecryptForTx(permit: Permit | null): Promise { this.assertPublicClient(); const delay = this.config.mocks.sealOutputDelay; - return cofheMocksDecryptForTx(this.ctHash, 0 as FheTypes, permit, this.publicClient, delay); + const result = await cofheMocksDecryptForTx(this.ctHash, 0 as FheTypes, permit, this.publicClient, delay); + return result; } /** * In the production context, perform a true decryption with the CoFHE coprocessor. */ - private async productionDecryptForTx(permit: Permit | null): Promise { + private async productionDecryptForTx(permit: Permit | null): Promise { this.assertChainId(); this.assertPublicClient(); @@ -281,34 +284,26 @@ export class DecryptForTxBuilder extends BaseBuilder { // Extract chainId from signed permit const chainId = permit._signedDomain!.chainId; - let decryptedValue: bigint; - if (chainId === hardhat.id) { - decryptedValue = await this.mocksDecryptForTx(permit); + return await this.mocksDecryptForTx(permit); } else { - decryptedValue = await this.productionDecryptForTx(permit); + return await this.productionDecryptForTx(permit); } - - return { - decryptedValue, - proof: '', // TODO: actual proof structure when available - }; } else { // Global allowance - no permit - this.assertChainId(); + // If chainId not set, try to get it from publicClient + if (!this.chainId) { + this.assertPublicClient(); + this.chainId = await getPublicClientChainID(this.publicClient); + } - let decryptedValue: bigint; + this.assertChainId(); if (this.chainId === hardhat.id) { - decryptedValue = await this.mocksDecryptForTx(null); + return await this.mocksDecryptForTx(null); } else { - decryptedValue = await this.productionDecryptForTx(null); + return await this.productionDecryptForTx(null); } - - return { - decryptedValue, - proof: '', // TODO: actual proof structure when available - }; } } } From 1016f2a19b9647df3eb0700ab8545447eff1a993 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 17:24:44 +0200 Subject: [PATCH 19/24] test: FHE(a+b) + decryptForTx + publishDecryptResult + verify decrypted result --- .../contracts/SimpleTest.sol | 12 +++ .../test/decrypt-with-proof.test.ts | 93 ++++++++++++------- .../core/decrypt/cofheMocksDecryptForTx.ts | 14 ++- 3 files changed, 85 insertions(+), 34 deletions(-) diff --git a/packages/hardhat-plugin-test/contracts/SimpleTest.sol b/packages/hardhat-plugin-test/contracts/SimpleTest.sol index fbd587bf..31d70eaa 100644 --- a/packages/hardhat-plugin-test/contracts/SimpleTest.sol +++ b/packages/hardhat-plugin-test/contracts/SimpleTest.sol @@ -29,6 +29,18 @@ contract SimpleTest { FHE.allowSender(storedValue); } + /** + * Add an encrypted value to the stored value + * @param inValue The encrypted value to add + */ + function addValue(InEuint32 memory inValue) public { + euint32 valueToAdd = FHE.asEuint32(inValue); + storedValue = FHE.add(storedValue, valueToAdd); + storedValueHash = uint256(euint32.unwrap(storedValue)); + FHE.allowThis(storedValue); + FHE.allowSender(storedValue); + } + /** * Get the stored encrypted value * @return The encrypted value diff --git a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts index 753c9d43..e861b58c 100644 --- a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts +++ b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts @@ -1,53 +1,80 @@ import hre from 'hardhat'; import { expect } from 'chai'; import { TASK_COFHE_MOCKS_DEPLOY } from './consts'; -import { Wallet, keccak256, solidityPacked, toBeHex } from 'ethers'; +import { CofheClient, Encryptable } from '@cofhe/sdk'; +import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'; +import { Wallet } from 'ethers'; -// Minimal happy-path test for TestBed.publishDecryptResult -// This verifies we can publish a decrypt result with a valid signature and read it back. +// Test the full workflow: +// 1. Encrypt values and submit on-chain +// 2. Perform FHE operation (add) +// 3. Use decryptForTx to get ctHash, decryptedValue, and signature +// 4. Call publishDecryptResult with those values +// 5. Verify with getDecryptResultSafe describe('Decrypt With Proof Test', () => { - it('Should publish decrypt result (happy path)', async () => { + let cofheClient: CofheClient; + let testContract: any; + let signer: HardhatEthersSigner; + let testBed: any; + + before(async function () { await hre.run(TASK_COFHE_MOCKS_DEPLOY); + const [tmpSigner] = await hre.ethers.getSigners(); + signer = tmpSigner; + cofheClient = await hre.cofhe.createClientWithBatteries(signer); - const taskManager = await hre.cofhe.mocks.getMockTaskManager(); - const testBed = await hre.cofhe.mocks.getTestBed(); + // Deploy test contract for FHE operations + const SimpleTest = await hre.ethers.getContractFactory('SimpleTest'); + testContract = await SimpleTest.deploy(); + await testContract.waitForDeployment(); - // Signer used by publishDecryptResult signature verification - const signerPrivateKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const signerWallet = new Wallet(signerPrivateKey); + testBed = await hre.cofhe.mocks.getTestBed(); + }); - await taskManager.setDecryptResultSigner(signerWallet.address); + it('Should encrypt, compute FHE operation, decrypt, and publish result', async function () { + // Step 1: Encrypt two values + const valueX = 100n; + const valueY = 50n; + const expectedSum = valueX + valueY; // 150 - // ctHash layout: last 2 bytes are metadata - // - byte 0: securityZone - // - byte 1: utype - // For uint32 TFHE, utype is 4 (Utils.EUINT32_TFHE) - const securityZone = 0; - const utype = 4; + const [encX, encY] = await cofheClient + .encryptInputs([Encryptable.uint32(valueX), Encryptable.uint32(valueY)]) + .execute(); - const base = BigInt(keccak256(solidityPacked(['string'], ['mock-ct-hash']))) & ~0xffffn; - const ctHash = base | (BigInt(utype) << 8n) | BigInt(securityZone); + // Step 2: Submit encrypted values on-chain and perform FHE.add + const tx1 = await testContract.connect(signer).setValue(encX); + await tx1.wait(); - const result = 424242n; + const tx2 = await testContract.connect(signer).addValue(encY); + await tx2.wait(); - const ctHashBytes32 = toBeHex(ctHash, 32); + const resultCtHash = await testContract.getValue(); - const digest = keccak256( - solidityPacked( - ['uint256', 'uint32', 'uint64', 'bytes32'], - [result, utype, BigInt((await hre.ethers.provider.getNetwork()).chainId), ctHashBytes32] - ) - ); + // Step 3: Use decryptForTx to get the values needed for publishDecryptResult + const decryptResult = await cofheClient.decryptForTx(resultCtHash).execute(); - const sig = signerWallet.signingKey.sign(digest); - const signature = hre.ethers.concat([sig.r, sig.s, hre.ethers.toBeHex(sig.v, 1)]); + expect(decryptResult.ctHash).to.equal(resultCtHash); + expect(decryptResult.decryptedValue).to.equal(expectedSum); + expect(decryptResult.signature).to.be.a('string'); + + // Step 4: Publish the decrypt result on-chain + // Configure the mock task manager to accept the mock signature + const taskManager = await hre.cofhe.mocks.getMockTaskManager(); + const mockPrivateKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'; + const messageSigner = new Wallet(mockPrivateKey); + const signature = `0x${decryptResult.signature}`; + const setSignerTx = await taskManager.connect(signer).setDecryptResultSigner(messageSigner.address); + await setSignerTx.wait(); - const tx = await testBed.publishDecryptResult(ctHashBytes32, result, signature); - await tx.wait(); + // Publish the decrypt result on-chain + // publishDecryptResult expects (euint32, uint32, bytes signature) + const publishTx = await testBed.publishDecryptResult(decryptResult.ctHash, decryptResult.decryptedValue, signature); + await publishTx.wait(); - const [value, decrypted] = await testBed.getDecryptResultSafe(ctHashBytes32); - expect(decrypted).to.equal(true); - expect(value).to.equal(result); + // Step 5: Verify the published result + const [publishedValue, isDecrypted] = await testBed.getDecryptResultSafe(decryptResult.ctHash); + expect(isDecrypted).to.equal(true); + expect(publishedValue).to.equal(expectedSum); }); }); diff --git a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts index 3bf4f42e..be6ad849 100644 --- a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts +++ b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts @@ -5,6 +5,7 @@ import { sleep } from '../utils.js'; import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js'; import { FheTypes } from '../types.js'; import { CofheError, CofheErrorCode } from '../error.js'; +import { SigningKey, keccak256, solidityPacked, toBeHex, zeroPadValue } from 'ethers'; import { MOCKS_QUERY_DECRYPTER_ADDRESS } from '../consts.js'; export type DecryptForTxMocksResult = { @@ -72,7 +73,18 @@ export async function cofheMocksDecryptForTx( // decryptForTx returns plaintext directly (no sealing/unsealing needed) // Generate a mock threshold network signature (in production, this would be the actual signature) - const signature = `0x${ctHash.toString(16).padStart(64, '0')}`; + // The signature must be valid for MockTaskManager verification. + const chainId = await publicClient.getChainId(); + const ctHashBigInt = BigInt(ctHash); + const resultBigInt = BigInt(result); + const encryptionType = Number((ctHashBigInt & (0x7fn << 8n)) >> 8n); + const packed = solidityPacked( + ['uint256', 'uint32', 'uint64', 'bytes32'], + [resultBigInt, encryptionType, BigInt(chainId), zeroPadValue(toBeHex(ctHashBigInt), 32)] + ); + const messageHash = keccak256(packed); + const mockPrivateKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'; + const signature = new SigningKey(mockPrivateKey).sign(messageHash).serialized.slice(2); // no 0x prefix return { ctHash, From 25aca41bf4096ddd376047ea42856d6472ea11b0 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 17:40:20 +0200 Subject: [PATCH 20/24] chore: centralize the signer used for setDecryptResultSigner --- packages/hardhat-plugin-test/package.json | 2 +- .../hardhat-plugin-test/test/decrypt-with-proof.test.ts | 5 ++--- packages/sdk/core/consts.ts | 4 ++++ packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts | 6 ++++-- packages/sdk/core/index.ts | 1 + 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/hardhat-plugin-test/package.json b/packages/hardhat-plugin-test/package.json index 37d86f08..4c220bf6 100644 --- a/packages/hardhat-plugin-test/package.json +++ b/packages/hardhat-plugin-test/package.json @@ -2,7 +2,7 @@ "name": "@cofhe/hardhat-plugin(tests)", "private": true, "scripts": { - "test": "npx hardhat test", + "test": "pnpm -C ../sdk build && npx hardhat test", "test:integration": "npx hardhat test test/integration-*.test.ts", "compile": "npx hardhat compile", "clean": "npx hardhat clean" diff --git a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts index e861b58c..c28d81af 100644 --- a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts +++ b/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts @@ -1,7 +1,7 @@ import hre from 'hardhat'; import { expect } from 'chai'; import { TASK_COFHE_MOCKS_DEPLOY } from './consts'; -import { CofheClient, Encryptable } from '@cofhe/sdk'; +import { CofheClient, Encryptable, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY } from '@cofhe/sdk'; import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'; import { Wallet } from 'ethers'; @@ -61,8 +61,7 @@ describe('Decrypt With Proof Test', () => { // Step 4: Publish the decrypt result on-chain // Configure the mock task manager to accept the mock signature const taskManager = await hre.cofhe.mocks.getMockTaskManager(); - const mockPrivateKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'; - const messageSigner = new Wallet(mockPrivateKey); + const messageSigner = new Wallet(MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY); const signature = `0x${decryptResult.signature}`; const setSignerTx = await taskManager.connect(signer).setDecryptResultSigner(messageSigner.address); await setSignerTx.wait(); diff --git a/packages/sdk/core/consts.ts b/packages/sdk/core/consts.ts index 6fd79877..8e429e99 100644 --- a/packages/sdk/core/consts.ts +++ b/packages/sdk/core/consts.ts @@ -16,3 +16,7 @@ export const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = /** Address for the Mock ZK Verifier signer account */ export const MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = '0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2' as const; + +/** Private key for the Mock decrypt result signer account */ +export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = + '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' as const; diff --git a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts index be6ad849..0389f3ed 100644 --- a/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts +++ b/packages/sdk/core/decrypt/cofheMocksDecryptForTx.ts @@ -5,6 +5,7 @@ import { sleep } from '../utils.js'; import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js'; import { FheTypes } from '../types.js'; import { CofheError, CofheErrorCode } from '../error.js'; +import { MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY } from '../consts.js'; import { SigningKey, keccak256, solidityPacked, toBeHex, zeroPadValue } from 'ethers'; import { MOCKS_QUERY_DECRYPTER_ADDRESS } from '../consts.js'; @@ -83,8 +84,9 @@ export async function cofheMocksDecryptForTx( [resultBigInt, encryptionType, BigInt(chainId), zeroPadValue(toBeHex(ctHashBigInt), 32)] ); const messageHash = keccak256(packed); - const mockPrivateKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'; - const signature = new SigningKey(mockPrivateKey).sign(messageHash).serialized.slice(2); // no 0x prefix + const signature = new SigningKey(MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY) + .sign(messageHash) + .serialized.slice(2); // no 0x prefix return { ctHash, diff --git a/packages/sdk/core/index.ts b/packages/sdk/core/index.ts index 99942b91..e5256145 100644 --- a/packages/sdk/core/index.ts +++ b/packages/sdk/core/index.ts @@ -91,6 +91,7 @@ export { MOCKS_ZK_VERIFIER_ADDRESS, MOCKS_ZK_VERIFIER_SIGNER_ADDRESS, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, + MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_QUERY_DECRYPTER_ADDRESS, TEST_BED_ADDRESS, } from './consts.js'; From 5486ec2e5fa079add360934df30e073d5f978a66 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 17:49:31 +0200 Subject: [PATCH 21/24] tests: when trying to fetch without permit what is not global - error --- .../test/decrypt-for-tx.test.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts index 1499c4a0..04a875bc 100644 --- a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts +++ b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts @@ -23,28 +23,33 @@ describe('DecryptForTx Integration Tests', () => { }); describe('decryptForTx with global allowance', () => { - it('Should decrypt a value without a permit', async function () { + it('Should fail to decrypt without a permit when not globally allowed', async function () { const testValue = 42n; const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); const tx = await testContract.connect(signer).setValue(encrypted[0]); await tx.wait(); - const result = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); - - expect(result.ctHash).to.be.equal(encrypted[0].ctHash); - expect(result.decryptedValue).to.be.equal(testValue); - expect(result.signature).to.be.a('string'); + try { + await cofheClient.decryptForTx(encrypted[0].ctHash).withPermit(undefined).execute(); + expect.fail('Expected decryptForTx to fail without global allowance'); + } catch (error) { + expect((error as Error).message).to.include('NotAllowed'); + } }); - it('Should decrypt different values consistently', async function () { + it('Should decrypt different values consistently with a permit', async function () { const testValues = [1n, 100n, 1000n, 65535n]; + const permit = await cofheClient.permits.createSelf({ + issuer: signer.address, + name: 'Consistency Permit', + }); for (const testValue of testValues) { const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); const tx = await testContract.connect(signer).setValue(encrypted[0]); await tx.wait(); - const result = await cofheClient.decryptForTx(encrypted[0].ctHash).execute(); + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).withPermit(permit).execute(); expect(result.ctHash).to.be.equal(encrypted[0].ctHash); expect(result.decryptedValue).to.be.equal(testValue); expect(result.signature).to.be.a('string'); From cfa2b0b4c7af9db9690c04b259f633b23468f387 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 18:02:21 +0200 Subject: [PATCH 22/24] test: add a successful test without permit (public value) --- .../hardhat-plugin-test/contracts/SimpleTest.sol | 12 ++++++++++++ .../hardhat-plugin-test/test/decrypt-for-tx.test.ts | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/packages/hardhat-plugin-test/contracts/SimpleTest.sol b/packages/hardhat-plugin-test/contracts/SimpleTest.sol index 31d70eaa..6ce878da 100644 --- a/packages/hardhat-plugin-test/contracts/SimpleTest.sol +++ b/packages/hardhat-plugin-test/contracts/SimpleTest.sol @@ -10,6 +10,8 @@ import '@fhenixprotocol/cofhe-contracts/FHE.sol'; contract SimpleTest { euint32 public storedValue; uint256 public storedValueHash; + euint32 public publicValue; + uint256 public publicValueHash; function setValueTrivial(uint256 inValue) public { storedValue = FHE.asEuint32(inValue); @@ -18,6 +20,16 @@ contract SimpleTest { FHE.allowSender(storedValue); } + /** + * Set a globally accessible encrypted value (everyone can decrypt) + * @param inValue The encrypted value to set globally + */ + function setPublicValue(InEuint32 memory inValue) public { + publicValue = FHE.asEuint32(inValue); + publicValueHash = uint256(euint32.unwrap(publicValue)); + FHE.allowPublic(publicValue); + } + /** * Store an encrypted value * @param inValue The encrypted value to store diff --git a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts index 04a875bc..0cedf33b 100644 --- a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts +++ b/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts @@ -37,6 +37,19 @@ describe('DecryptForTx Integration Tests', () => { } }); + it('Should successfully decrypt without a permit when globally allowed', async function () { + const testValue = 55n; + const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); + const tx = await testContract.connect(signer).setPublicValue(encrypted[0]); + await tx.wait(); + + const result = await cofheClient.decryptForTx(encrypted[0].ctHash).withPermit(undefined).execute(); + + expect(result.ctHash).to.be.equal(encrypted[0].ctHash); + expect(result.decryptedValue).to.be.equal(testValue); + expect(result.signature).to.be.a('string'); + }); + it('Should decrypt different values consistently with a permit', async function () { const testValues = [1n, 100n, 1000n, 65535n]; const permit = await cofheClient.permits.createSelf({ From 67697e4b2c792434f26244b7aa7db1f44e18c1e6 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 18:05:53 +0200 Subject: [PATCH 23/24] chore: better naming for tests --- .../test/{decrypt-for-tx.test.ts => decryptForTx-builder.test.ts} | 0 .../{decrypt-with-proof.test.ts => decryptForTx-publish.test.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/hardhat-plugin-test/test/{decrypt-for-tx.test.ts => decryptForTx-builder.test.ts} (100%) rename packages/hardhat-plugin-test/test/{decrypt-with-proof.test.ts => decryptForTx-publish.test.ts} (100%) diff --git a/packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts b/packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts similarity index 100% rename from packages/hardhat-plugin-test/test/decrypt-for-tx.test.ts rename to packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts diff --git a/packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts b/packages/hardhat-plugin-test/test/decryptForTx-publish.test.ts similarity index 100% rename from packages/hardhat-plugin-test/test/decrypt-with-proof.test.ts rename to packages/hardhat-plugin-test/test/decryptForTx-publish.test.ts From a678ea76d178714c49ce4d843e5b665c598f1464 Mon Sep 17 00:00:00 2001 From: Alexey Shchur Date: Wed, 25 Feb 2026 18:16:23 +0200 Subject: [PATCH 24/24] chore: rename decryptHandle to decryptForView --- .../test/decryptForTx-builder.test.ts | 8 +++---- .../test/encrypt-inputs.test.ts | 2 +- .../test/integration-base-sepolia.test.ts | 2 +- .../test/integration-hardhat.test.ts | 2 +- .../test/integration-localcofhe.test.ts | 2 +- .../test/permit-unseal.test.ts | 2 +- packages/react/src/hooks/useCofheDecrypt.ts | 2 +- packages/sdk/core/client.ts | 8 +++---- packages/sdk/core/clientTypes.ts | 4 ++-- ...dleBuilder.ts => decryptForViewBuilder.ts} | 24 +++++++++---------- packages/sdk/core/index.ts | 2 +- packages/sdk/node/client.test.ts | 4 ++-- packages/sdk/web/client.web.test.ts | 4 ++-- 13 files changed, 33 insertions(+), 33 deletions(-) rename packages/sdk/core/decrypt/{decryptHandleBuilder.ts => decryptForViewBuilder.ts} (92%) diff --git a/packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts b/packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts index 0cedf33b..8e29ccca 100644 --- a/packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts +++ b/packages/hardhat-plugin-test/test/decryptForTx-builder.test.ts @@ -146,7 +146,7 @@ describe('DecryptForTx Integration Tests', () => { // Error handling tests - can be extended as needed }); - describe('decryptForTx vs decryptHandle', () => { + describe('decryptForTx vs decryptForView', () => { it('Should return plaintext value', async function () { const testValue = 123n; const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); @@ -160,17 +160,17 @@ describe('DecryptForTx Integration Tests', () => { expect(typeof decryptForTxResult.signature).to.equal('string'); }); - it('Should support both decryptHandle and decryptForTx', async function () { + it('Should support both decryptForView and decryptForTx', async function () { const testValue = 234n; const encrypted = await cofheClient.encryptInputs([Encryptable.uint32(testValue)]).execute(); const tx = await testContract.connect(signer).setValue(encrypted[0]); await tx.wait(); const ctHash = encrypted[0].ctHash; - const handleResult = await cofheClient.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const viewResult = await cofheClient.decryptForView(ctHash, FheTypes.Uint32).execute(); const forTxResult = await cofheClient.decryptForTx(ctHash).execute(); - expect(handleResult).to.be.equal(testValue); + expect(viewResult).to.be.equal(testValue); expect(forTxResult.ctHash).to.be.equal(ctHash); expect(forTxResult.decryptedValue).to.be.equal(testValue); }); diff --git a/packages/hardhat-plugin-test/test/encrypt-inputs.test.ts b/packages/hardhat-plugin-test/test/encrypt-inputs.test.ts index 07b34b9d..6f2e1490 100644 --- a/packages/hardhat-plugin-test/test/encrypt-inputs.test.ts +++ b/packages/hardhat-plugin-test/test/encrypt-inputs.test.ts @@ -19,7 +19,7 @@ describe('Encrypt Inputs Test', () => { const ctHash = await testBed.numberHash(); // Decrypt number from TestBed - const unsealed = await client.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const unsealed = await client.decryptForView(ctHash, FheTypes.Uint32).execute(); expect(unsealed).to.be.equal(7n); }); diff --git a/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts b/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts index 60abd891..b55bb216 100644 --- a/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts +++ b/packages/hardhat-plugin-test/test/integration-base-sepolia.test.ts @@ -109,7 +109,7 @@ describe('Base Sepolia Integration Tests', () => { const ctHash = await testContract.getValueHash(); // Decrypt the value using the ctHash from the encrypted input - const unsealedResult = await cofheClient.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const unsealedResult = await cofheClient.decryptForView(ctHash, FheTypes.Uint32).execute(); // Verify the decrypted value matches expect(unsealedResult).to.be.equal(testValue); diff --git a/packages/hardhat-plugin-test/test/integration-hardhat.test.ts b/packages/hardhat-plugin-test/test/integration-hardhat.test.ts index 271563e9..8d9d33e1 100644 --- a/packages/hardhat-plugin-test/test/integration-hardhat.test.ts +++ b/packages/hardhat-plugin-test/test/integration-hardhat.test.ts @@ -42,7 +42,7 @@ describe('Hardhat Integration Tests', () => { await tx.wait(); // Decrypt the value using the ctHash from the encrypted input - const unsealedResult = await cofheClient.decryptHandle(encrypted[0].ctHash, FheTypes.Uint32).execute(); + const unsealedResult = await cofheClient.decryptForView(encrypted[0].ctHash, FheTypes.Uint32).execute(); // Verify the decrypted value matches expect(unsealedResult).to.be.equal(testValue); diff --git a/packages/hardhat-plugin-test/test/integration-localcofhe.test.ts b/packages/hardhat-plugin-test/test/integration-localcofhe.test.ts index cd91412c..38db64cd 100644 --- a/packages/hardhat-plugin-test/test/integration-localcofhe.test.ts +++ b/packages/hardhat-plugin-test/test/integration-localcofhe.test.ts @@ -96,7 +96,7 @@ describe('Local Cofhe Integration Tests', () => { const ctHash = await testContract.getValueHash(); // Decrypt the value using the ctHash from the encrypted input - const unsealedResult = await cofheClient.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const unsealedResult = await cofheClient.decryptForView(ctHash, FheTypes.Uint32).execute(); // Verify the decrypted value matches expect(unsealedResult).to.be.equal(testValue); diff --git a/packages/hardhat-plugin-test/test/permit-unseal.test.ts b/packages/hardhat-plugin-test/test/permit-unseal.test.ts index bc9a7255..4d58108c 100644 --- a/packages/hardhat-plugin-test/test/permit-unseal.test.ts +++ b/packages/hardhat-plugin-test/test/permit-unseal.test.ts @@ -17,7 +17,7 @@ describe('Permit Unseal Test', () => { const ctHash = await testBed.numberHash(); // Decrypt number from TestBed - const unsealed = await client.decryptHandle(ctHash, FheTypes.Uint32).execute(); + const unsealed = await client.decryptForView(ctHash, FheTypes.Uint32).execute(); expect(unsealed).to.be.equal(7n); }); diff --git a/packages/react/src/hooks/useCofheDecrypt.ts b/packages/react/src/hooks/useCofheDecrypt.ts index e8633a37..7408a600 100644 --- a/packages/react/src/hooks/useCofheDecrypt.ts +++ b/packages/react/src/hooks/useCofheDecrypt.ts @@ -30,7 +30,7 @@ export function useCofheDecrypt { assert(input, 'input is guaranteed to be defined by enabled condition'); - return client.decryptHandle(input.ctHash, input.utype).execute(); + return client.decryptForView(input.ctHash, input.utype).execute(); }, meta: { persist: true, diff --git a/packages/sdk/core/client.ts b/packages/sdk/core/client.ts index 5e54b878..7e07a45d 100644 --- a/packages/sdk/core/client.ts +++ b/packages/sdk/core/client.ts @@ -6,7 +6,7 @@ import { CofheError, CofheErrorCode } from './error.js'; import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; import { createKeysStore } from './keyStore.js'; import { permits } from './permits.js'; -import { DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +import { DecryptForViewBuilder } from './decrypt/decryptForViewBuilder.js'; import { DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; import { getPublicClientChainID, getWalletClientAccount } from './utils.js'; import type { CofheClientConnectionState, CofheClientParams, CofheClient, CofheClientPermits } from './clientTypes.js'; @@ -146,10 +146,10 @@ export function createCofheClientBase( }); } - function decryptHandle(ctHash: bigint, utype: U): DecryptHandlesBuilder { + function decryptForView(ctHash: bigint, utype: U): DecryptForViewBuilder { const state = connectStore.getState(); - return new DecryptHandlesBuilder({ + return new DecryptForViewBuilder({ ctHash, utype, chainId: state.chainId ?? undefined, @@ -314,7 +314,7 @@ export function createCofheClientBase( connect, disconnect, encryptInputs, - decryptHandle, + decryptForView, decryptForTx, permits: clientPermits, diff --git a/packages/sdk/core/clientTypes.ts b/packages/sdk/core/clientTypes.ts index 3a90e616..4dd9e3d3 100644 --- a/packages/sdk/core/clientTypes.ts +++ b/packages/sdk/core/clientTypes.ts @@ -1,7 +1,7 @@ // TODO: Extract client types to its own file, keep this one as primitives import { type PublicClient, type WalletClient } from 'viem'; import { type CofheConfig } from './config.js'; -import { type DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +import { type DecryptForViewBuilder } from './decrypt/decryptForViewBuilder.js'; import { type DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; import { type EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; import { type ZkBuilderAndCrsGenerator, type ZkProveWorkerFunction } from './encrypt/zkPackProveVerify.js'; @@ -45,7 +45,7 @@ export type CofheClient = { * Types docstring */ encryptInputs(inputs: [...T]): EncryptInputsBuilder<[...T]>; - decryptHandle(ctHash: bigint, utype: U): DecryptHandlesBuilder; + decryptForView(ctHash: bigint, utype: U): DecryptForViewBuilder; decryptForTx(ctHash: bigint): DecryptForTxBuilder; permits: CofheClientPermits; }; diff --git a/packages/sdk/core/decrypt/decryptHandleBuilder.ts b/packages/sdk/core/decrypt/decryptForViewBuilder.ts similarity index 92% rename from packages/sdk/core/decrypt/decryptHandleBuilder.ts rename to packages/sdk/core/decrypt/decryptForViewBuilder.ts index 10858869..c537b763 100644 --- a/packages/sdk/core/decrypt/decryptHandleBuilder.ts +++ b/packages/sdk/core/decrypt/decryptForViewBuilder.ts @@ -15,7 +15,7 @@ import { cofheMocksDecryptForTx } from './cofheMocksDecryptForTx.js'; /** * API * - * await client.decryptHandle(ctHash, utype) + * await client.decryptForView(ctHash, utype) * .setChainId(chainId) * .setAccount(account) * .setPermitHash(permitHash) @@ -30,20 +30,20 @@ import { cofheMocksDecryptForTx } from './cofheMocksDecryptForTx.js'; * Returns the unsealed item. */ -type DecryptHandlesBuilderParams = BaseBuilderParams & { +type DecryptForViewBuilderParams = BaseBuilderParams & { ctHash: bigint; utype: U; permitHash?: string; permit?: Permit; }; -export class DecryptHandlesBuilder extends BaseBuilder { +export class DecryptForViewBuilder extends BaseBuilder { private ctHash: bigint; private utype: U; private permitHash?: string; private permit?: Permit; - constructor(params: DecryptHandlesBuilderParams) { + constructor(params: DecryptForViewBuilderParams) { super({ config: params.config, publicClient: params.publicClient, @@ -71,9 +71,9 @@ export class DecryptHandlesBuilder extends BaseBuilder { * .execute(); * ``` * - * @returns The chainable DecryptHandlesBuilder instance. + * @returns The chainable DecryptForViewBuilder instance. */ - setChainId(chainId: number): DecryptHandlesBuilder { + setChainId(chainId: number): DecryptForViewBuilder { this.chainId = chainId; return this; } @@ -94,9 +94,9 @@ export class DecryptHandlesBuilder extends BaseBuilder { * .execute(); * ``` * - * @returns The chainable DecryptHandlesBuilder instance. + * @returns The chainable DecryptForViewBuilder instance. */ - setAccount(account: string): DecryptHandlesBuilder { + setAccount(account: string): DecryptForViewBuilder { this.account = account; return this; } @@ -118,9 +118,9 @@ export class DecryptHandlesBuilder extends BaseBuilder { * .execute(); * ``` * - * @returns The chainable DecryptHandlesBuilder instance. + * @returns The chainable DecryptForViewBuilder instance. */ - setPermitHash(permitHash: string): DecryptHandlesBuilder { + setPermitHash(permitHash: string): DecryptForViewBuilder { this.permitHash = permitHash; return this; } @@ -141,9 +141,9 @@ export class DecryptHandlesBuilder extends BaseBuilder { * .execute(); * ``` * - * @returns The chainable DecryptHandlesBuilder instance. + * @returns The chainable DecryptForViewBuilder instance. */ - setPermit(permit: Permit): DecryptHandlesBuilder { + setPermit(permit: Permit): DecryptForViewBuilder { this.permit = permit; return this; } diff --git a/packages/sdk/core/index.ts b/packages/sdk/core/index.ts index e5256145..6ad4bf5e 100644 --- a/packages/sdk/core/index.ts +++ b/packages/sdk/core/index.ts @@ -72,7 +72,7 @@ export type { KeysStorage, KeysStore } from './keyStore.js'; // Builders (exported via client, but can be imported directly for typing) export { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js'; -export { DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js'; +export { DecryptForViewBuilder } from './decrypt/decryptForViewBuilder.js'; export { DecryptForTxBuilder } from './decrypt/decryptForTxBuilder.js'; export type { DecryptForTxResult } from './decrypt/decryptForTxBuilder.js'; diff --git a/packages/sdk/node/client.test.ts b/packages/sdk/node/client.test.ts index bd5b2c1b..94b8b2f8 100644 --- a/packages/sdk/node/client.test.ts +++ b/packages/sdk/node/client.test.ts @@ -54,7 +54,7 @@ describe('@cofhe/node - Client Integration Tests', () => { it('should have all expected methods', () => { expect(typeof cofheClient.connect).toBe('function'); expect(typeof cofheClient.encryptInputs).toBe('function'); - expect(typeof cofheClient.decryptHandle).toBe('function'); + expect(typeof cofheClient.decryptForView).toBe('function'); expect(typeof cofheClient.getSnapshot).toBe('function'); expect(typeof cofheClient.subscribe).toBe('function'); }); @@ -136,7 +136,7 @@ describe('@cofhe/node - Client Integration Tests', () => { it('should create decrypt builder after connection', async () => { await cofheClient.connect(publicClient, walletClient); - const builder = cofheClient.decryptHandle(123n, 2); + const builder = cofheClient.decryptForView(123n, 2); expect(builder).toBeDefined(); expect(typeof builder.setChainId).toBe('function'); diff --git a/packages/sdk/web/client.web.test.ts b/packages/sdk/web/client.web.test.ts index ad339964..10a29664 100644 --- a/packages/sdk/web/client.web.test.ts +++ b/packages/sdk/web/client.web.test.ts @@ -54,7 +54,7 @@ describe('@cofhe/web - Client', () => { it('should have all expected methods', () => { expect(typeof cofheClient.connect).toBe('function'); expect(typeof cofheClient.encryptInputs).toBe('function'); - expect(typeof cofheClient.decryptHandle).toBe('function'); + expect(typeof cofheClient.decryptForView).toBe('function'); expect(typeof cofheClient.getSnapshot).toBe('function'); expect(typeof cofheClient.subscribe).toBe('function'); }); @@ -136,7 +136,7 @@ describe('@cofhe/web - Client', () => { it('should create decrypt builder after connection', async () => { await cofheClient.connect(publicClient, walletClient); - const builder = cofheClient.decryptHandle(123n, 2); + const builder = cofheClient.decryptForView(123n, 2); expect(builder).toBeDefined(); expect(typeof builder.setChainId).toBe('function');