From 7cbbf0d2fc68693e9bafdd1b9efd5cf52a8964f4 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Fri, 13 Mar 2026 19:41:41 +0500 Subject: [PATCH 01/11] feat: implement parametric E3 pricing --- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IEnclave.sol/IEnclave.json | 212 ++++- .../ISlashingManager.json | 2 +- .../enclave-contracts/contracts/Enclave.sol | 115 ++- .../contracts/interfaces/IEnclave.sol | 25 + .../scripts/deployEnclave.ts | 17 + .../test/Pricing/Pricing.spec.ts | 791 ++++++++++++++++++ 8 files changed, 1155 insertions(+), 11 deletions(-) create mode 100644 packages/enclave-contracts/test/Pricing/Pricing.spec.ts diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 7f9de47db8..9de33c2762 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-dbd94fb7bf5c147a4effe4d89ec8d62bae78112f" + "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index 6407b1521d..82976161e4 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -782,5 +782,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-dbd94fb7bf5c147a4effe4d89ec8d62bae78112f" + "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index 5c5263a687..b09285ebd7 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -427,6 +427,76 @@ "name": "PlaintextOutputPublished", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationPerByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "indexed": false, + "internalType": "struct IEnclave.PricingConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "PricingConfigUpdated", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -851,6 +921,76 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getPricingConfig", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationPerByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "internalType": "struct IEnclave.PricingConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1276,6 +1416,76 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationPerByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "internalType": "struct IEnclave.PricingConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setPricingConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1313,5 +1523,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-dbd94fb7bf5c147a4effe4d89ec8d62bae78112f" + "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 48541a975b..21ebe50508 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-dbd94fb7bf5c147a4effe4d89ec8d62bae78112f" + "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index 743c8c3ba4..aef63b9836 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -104,6 +104,12 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @notice Global timeout configuration E3TimeoutConfig internal _timeoutConfig; + /// @notice All pricing-related configuration + PricingConfig internal _pricingConfig; + + /// @notice Basis points denominator + uint16 internal constant BPS_BASE = 10000; + //////////////////////////////////////////////////////////// // // // Errors // @@ -274,6 +280,22 @@ contract Enclave is IEnclave, OwnableUpgradeable { setFeeToken(_feeToken); _setTimeoutConfig(config); setE3ProgramsParams(_e3ProgramsParams); + + // Set default pricing parameters + _pricingConfig = PricingConfig({ + keyGenPerNode: 100000, // 0.10 USDC + coordinationPerPair: 5000, // 0.005 USDC + availabilityPerNodePerSec: 20, // 0.00002 USDC + decryptionPerNode: 150000, // 0.15 USDC + publicationBase: 500000, // 0.50 USDC + publicationPerByte: 10, // 0.00001 USDC + protocolTreasury: address(0), + marginBps: 1000, // 10% + protocolShareBps: 0, + minCommitteeSize: 0, + minThreshold: 0 + }); + if (_owner != owner()) transferOwnership(_owner); } @@ -530,19 +552,34 @@ contract Enclave is IEnclave, OwnableUpgradeable { uint256[] memory amounts = new uint256[](activeLength); - // Distribute equally among active (non-expelled) committee members - uint256 amount = totalAmount / activeLength; + // Split between protocol treasury and CN rewards + uint256 protocolAmount = 0; + uint16 _protocolShareBps = _pricingConfig.protocolShareBps; + address _protocolTreasury = _pricingConfig.protocolTreasury; + if (_protocolShareBps > 0 && _protocolTreasury != address(0)) { + protocolAmount = + (totalAmount * uint256(_protocolShareBps)) / + uint256(BPS_BASE); + if (protocolAmount > 0) { + paymentToken.safeTransfer(_protocolTreasury, protocolAmount); + } + } + + uint256 cnAmount = totalAmount - protocolAmount; + + // Distribute CN share equally among active (non-expelled) committee members + uint256 amount = cnAmount / activeLength; uint256 distributed = 0; for (uint256 i = 0; i < activeLength; i++) { amounts[i] = amount; distributed += amount; } - uint256 dust = totalAmount - distributed; + uint256 dust = cnAmount - distributed; if (dust > 0) { amounts[activeLength - 1] += dust; } - paymentToken.forceApprove(address(bondingRegistry), totalAmount); + paymentToken.forceApprove(address(bondingRegistry), cnAmount); bondingRegistry.distributeRewards(paymentToken, activeNodes, amounts); @@ -989,10 +1026,33 @@ contract Enclave is IEnclave, OwnableUpgradeable { threshold[1] >= threshold[0] && threshold[0] > 0, "Invalid threshold" ); + // Enforce minimum committee bounds if configured + PricingConfig memory pc = _pricingConfig; + if (pc.minCommitteeSize > 0) { + require( + threshold[1] >= pc.minCommitteeSize, + "Below min committee size" + ); + } + if (pc.minThreshold > 0) { + require(threshold[0] >= pc.minThreshold, "Below min threshold"); + } committeeThresholds[size] = threshold; emit CommitteeThresholdsUpdated(size, threshold); } + /// @inheritdoc IEnclave + function setPricingConfig(PricingConfig calldata config) public onlyOwner { + require(config.marginBps <= BPS_BASE, "Margin exceeds 100%"); + require(config.protocolShareBps <= BPS_BASE, "Share exceeds 100%"); + require( + config.minCommitteeSize >= config.minThreshold, + "Min size must be >= min threshold" + ); + _pricingConfig = config; + emit PricingConfigUpdated(config); + } + //////////////////////////////////////////////////////////// // // // Get Functions // @@ -1007,12 +1067,53 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @inheritdoc IEnclave function getE3Quote( - E3RequestParams calldata - ) public pure returns (uint256 fee) { - fee = 1 * 10 ** 6; + E3RequestParams calldata requestParams + ) public view returns (uint256 fee) { + uint32[2] memory threshold = committeeThresholds[ + requestParams.committeeSize + ]; + uint256 n = uint256(threshold[1]); // total committee size + uint256 m = uint256(threshold[0]); // quorum/decryption threshold + + PricingConfig memory pc = _pricingConfig; + + // Duration covers the full availability period + uint256 duration = requestParams.inputWindow[1] - + requestParams.inputWindow[0] + + _timeoutConfig.dkgWindow + + _timeoutConfig.computeWindow + + _timeoutConfig.decryptionWindow; + + // Key generation cost (linear in n) + uint256 baseFee = pc.keyGenPerNode * n; + // Key generation coordination cost (quadratic in n) + if (n > 1) { + baseFee += (pc.coordinationPerPair * (n * (n - 1))) / 2; + } + // Availability cost (linear in n * duration) + baseFee += pc.availabilityPerNodePerSec * n * duration; + // Decryption cost (linear in m) + baseFee += pc.decryptionPerNode * m; + // Decryption coordination cost (quadratic in m) + if (m > 1) { + baseFee += (pc.coordinationPerPair * (m * (m - 1))) / 2; + } + // Publication base cost + baseFee += pc.publicationBase; + + // Apply margin markup + fee = + (baseFee * (uint256(BPS_BASE) + uint256(pc.marginBps))) / + uint256(BPS_BASE); + require(fee > 0, PaymentRequired(fee)); } + /// @inheritdoc IEnclave + function getPricingConfig() external view returns (PricingConfig memory) { + return _pricingConfig; + } + /// @inheritdoc IEnclave function getDecryptionVerifier( bytes32 encryptionSchemeId diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index 031fd0cfc8..f180d6c3f4 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -76,6 +76,21 @@ interface IEnclave { uint256 decryptionDeadline; } + /// @notice All pricing-related configuration for parametric E3 fee calculation + struct PricingConfig { + uint256 keyGenPerNode; + uint256 coordinationPerPair; + uint256 availabilityPerNodePerSec; + uint256 decryptionPerNode; + uint256 publicationBase; + uint256 publicationPerByte; + address protocolTreasury; + uint16 marginBps; + uint16 protocolShareBps; + uint32 minCommitteeSize; + uint32 minThreshold; + } + //////////////////////////////////////////////////////////// // // // Events // @@ -220,6 +235,9 @@ interface IEnclave { uint32[2] threshold ); + /// @notice Emitted when pricing configuration is updated + event PricingConfigUpdated(PricingConfig config); + //////////////////////////////////////////////////////////// // // // Structs // @@ -340,6 +358,10 @@ interface IEnclave { /// @param _e3ProgramsParams Array of ABI encoded parameter sets to remove. function removeE3ProgramsParams(bytes[] memory _e3ProgramsParams) external; + /// @notice Sets the full pricing configuration. + /// @param config The new pricing configuration. + function setPricingConfig(PricingConfig calldata config) external; + //////////////////////////////////////////////////////////// // // // Get Functions // @@ -360,6 +382,9 @@ interface IEnclave { E3RequestParams calldata e3Params ) external view returns (uint256 fee); + /// @notice Returns the full pricing configuration. + function getPricingConfig() external view returns (PricingConfig memory); + /// @notice Returns the decryption verifier for a given encryption scheme. /// @param encryptionSchemeId The unique identifier for the encryption scheme. /// @return The decryption verifier contract for the specified encryption scheme. diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index 83ee4b8026..0823efb0db 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -218,6 +218,23 @@ export const deployEnclave = async (withMocks?: boolean) => { // Medium and Large can be set later as needed console.log("Committee thresholds set (Micro=[1,3], Small=[2,5])"); + // Set pricing config with protocol treasury + console.log("Setting pricing config..."); + await enclave.setPricingConfig({ + keyGenPerNode: 100000, // 0.10 USDC + coordinationPerPair: 5000, // 0.005 USDC + availabilityPerNodePerSec: 20, // 0.00002 USDC + decryptionPerNode: 150000, // 0.15 USDC + publicationBase: 500000, // 0.50 USDC + publicationPerByte: 10, // 0.00001 USDC + protocolTreasury: ownerAddress, + marginBps: 1000, // 10% + protocolShareBps: 2000, // 20% + minCommitteeSize: 0, + minThreshold: 0, + }); + console.log("Pricing config set (treasury:", ownerAddress, ")"); + if (shouldDeployMocks) { const { decryptionVerifierAddress, e3ProgramAddress } = await deployMocks(); diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts new file mode 100644 index 0000000000..6d5ad7de30 --- /dev/null +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -0,0 +1,791 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. +import { expect } from "chai"; +import type { Signer } from "ethers"; +import { network } from "hardhat"; + +import BondingRegistryModule from "../../ignition/modules/bondingRegistry"; +import CiphernodeRegistryModule from "../../ignition/modules/ciphernodeRegistry"; +import E3RefundManagerModule from "../../ignition/modules/e3RefundManager"; +import EnclaveModule from "../../ignition/modules/enclave"; +import EnclaveTicketTokenModule from "../../ignition/modules/enclaveTicketToken"; +import EnclaveTokenModule from "../../ignition/modules/enclaveToken"; +import mockComputeProviderModule from "../../ignition/modules/mockComputeProvider"; +import MockDecryptionVerifierModule from "../../ignition/modules/mockDecryptionVerifier"; +import MockE3ProgramModule from "../../ignition/modules/mockE3Program"; +import MockStableTokenModule from "../../ignition/modules/mockStableToken"; +import SlashingManagerModule from "../../ignition/modules/slashingManager"; +import { + BondingRegistry__factory as BondingRegistryFactory, + CiphernodeRegistryOwnable__factory as CiphernodeRegistryOwnableFactory, + Enclave__factory as EnclaveFactory, + MockUSDC__factory as MockUSDCFactory, +} from "../../types"; +import type { Enclave } from "../../types/contracts/Enclave"; +import type { MockUSDC } from "../../types/contracts/test/MockStableToken.sol/MockUSDC"; + +const { ethers, ignition, networkHelpers } = await network.connect(); +const { loadFixture, time, mine } = networkHelpers; + +describe("E3 Pricing", function () { + const THIRTY_DAYS_IN_SECONDS = 60 * 60 * 24 * 30; + const SORTITION_SUBMISSION_WINDOW = 10; + const addressOne = "0x0000000000000000000000000000000000000001"; + + const timeoutConfig = { + committeeFormationWindow: 3600, + dkgWindow: 3600, + computeWindow: 3600, + decryptionWindow: 3600, + }; + + // Default pricing config matching initialize() defaults + const defaultPricingConfig = { + keyGenPerNode: 100000n, + coordinationPerPair: 5000n, + availabilityPerNodePerSec: 20n, + decryptionPerNode: 150000n, + publicationBase: 500000n, + publicationPerByte: 10n, + protocolTreasury: ethers.ZeroAddress, + marginBps: 1000, + protocolShareBps: 0, + minCommitteeSize: 0, + minThreshold: 0, + }; + + // Convert ethers Result to a plain object that can be spread + const toPlainConfig = (pc: any) => ({ + keyGenPerNode: pc.keyGenPerNode, + coordinationPerPair: pc.coordinationPerPair, + availabilityPerNodePerSec: pc.availabilityPerNodePerSec, + decryptionPerNode: pc.decryptionPerNode, + publicationBase: pc.publicationBase, + publicationPerByte: pc.publicationPerByte, + protocolTreasury: pc.protocolTreasury, + marginBps: pc.marginBps, + protocolShareBps: pc.protocolShareBps, + minCommitteeSize: pc.minCommitteeSize, + minThreshold: pc.minThreshold, + }); + + const inputWindowDuration = 300; + + const encryptionSchemeId = + "0x2c2a814a0495f913a3a312fc4771e37552bc14f8a2d4075a08122d356f0849c6"; + + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const polynomial_degree = ethers.toBigInt(512); + const plaintext_modulus = ethers.toBigInt(10); + const moduli = [ + ethers.toBigInt("0xffffee001"), + ethers.toBigInt("0xffffc4001"), + ]; + const encodedE3ProgramParams = abiCoder.encode( + ["uint256", "uint256", "uint256[]"], + [polynomial_degree, plaintext_modulus, moduli], + ); + const data = "0xda7a"; + const proof = "0x1337"; + + async function setupOperatorForSortition( + operator: Signer, + bondingRegistry: any, + licenseToken: any, + usdcToken: any, + ticketToken: any, + registry: any, + ): Promise { + const operatorAddress = await operator.getAddress(); + await licenseToken.mintAllocation( + operatorAddress, + ethers.parseEther("10000"), + "Test allocation", + ); + await usdcToken.mint(operatorAddress, ethers.parseUnits("100000", 6)); + await licenseToken + .connect(operator) + .approve(await bondingRegistry.getAddress(), ethers.parseEther("2000")); + await bondingRegistry + .connect(operator) + .bondLicense(ethers.parseEther("1000")); + await bondingRegistry.connect(operator).registerOperator(); + const ticketAmount = ethers.parseUnits("100", 6); + await usdcToken + .connect(operator) + .approve(await ticketToken.getAddress(), ticketAmount); + await bondingRegistry.connect(operator).addTicketBalance(ticketAmount); + await registry.addCiphernode(operatorAddress); + } + + const setupAndPublishCommittee = async ( + registry: any, + e3Id: number, + nodes: string[], + publicKey: string, + operators: Signer[], + ): Promise => { + for (const operator of operators) { + await registry.connect(operator).submitTicket(e3Id, 1); + } + await time.increase(SORTITION_SUBMISSION_WINDOW + 1); + await registry.finalizeCommittee(e3Id); + const publicKeyHash = ethers.id(publicKey); + await registry.publishCommittee(e3Id, nodes, publicKey, publicKeyHash); + }; + + const setup = async () => { + const [owner, notTheOwner, operator1, operator2, operator3, treasury] = + await ethers.getSigners(); + const ownerAddress = await owner.getAddress(); + const treasuryAddress = await treasury.getAddress(); + + const { mockUSDC } = await ignition.deploy(MockStableTokenModule, { + parameters: { MockUSDC: { initialSupply: 1_000_000 } }, + }); + const usdcToken = MockUSDCFactory.connect( + await mockUSDC.getAddress(), + owner, + ); + + const { enclaveToken: licenseToken } = await ignition.deploy( + EnclaveTokenModule, + { parameters: { EnclaveToken: { owner: ownerAddress } } }, + ); + const { enclaveTicketToken: ticketToken } = await ignition.deploy( + EnclaveTicketTokenModule, + { + parameters: { + EnclaveTicketToken: { + baseToken: await usdcToken.getAddress(), + registry: addressOne, + owner: ownerAddress, + }, + }, + }, + ); + + const { slashingManager } = await ignition.deploy(SlashingManagerModule, { + parameters: { SlashingManager: { admin: ownerAddress } }, + }); + const { cipherNodeRegistry } = await ignition.deploy( + CiphernodeRegistryModule, + { + parameters: { + CiphernodeRegistry: { + owner: ownerAddress, + submissionWindow: SORTITION_SUBMISSION_WINDOW, + }, + }, + }, + ); + const ciphernodeRegistryAddress = await cipherNodeRegistry.getAddress(); + const ciphernodeRegistryContract = CiphernodeRegistryOwnableFactory.connect( + ciphernodeRegistryAddress, + owner, + ); + + const { bondingRegistry: _bondingRegistry } = await ignition.deploy( + BondingRegistryModule, + { + parameters: { + BondingRegistry: { + owner: ownerAddress, + ticketToken: await ticketToken.getAddress(), + licenseToken: await licenseToken.getAddress(), + registry: ciphernodeRegistryAddress, + slashedFundsTreasury: ownerAddress, + ticketPrice: ethers.parseUnits("10", 6), + licenseRequiredBond: ethers.parseEther("1000"), + minTicketBalance: 5, + exitDelay: 7 * 24 * 60 * 60, + }, + }, + }, + ); + const bondingRegistry = BondingRegistryFactory.connect( + await _bondingRegistry.getAddress(), + owner, + ); + + const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { + parameters: { + Enclave: { + params: encodedE3ProgramParams, + owner: ownerAddress, + maxDuration: THIRTY_DAYS_IN_SECONDS, + registry: ciphernodeRegistryAddress, + bondingRegistry: await bondingRegistry.getAddress(), + e3RefundManager: addressOne, + feeToken: await usdcToken.getAddress(), + timeoutConfig, + }, + }, + }); + const enclaveAddress = await _enclave.getAddress(); + const enclave = EnclaveFactory.connect(enclaveAddress, owner); + + const { e3RefundManager } = await ignition.deploy(E3RefundManagerModule, { + parameters: { + E3RefundManager: { + owner: ownerAddress, + enclave: enclaveAddress, + treasury: treasuryAddress, + }, + }, + }); + await enclave.setE3RefundManager(await e3RefundManager.getAddress()); + + // Wire up + await ciphernodeRegistryContract.setEnclave(enclaveAddress); + await ciphernodeRegistryContract.setBondingRegistry( + await bondingRegistry.getAddress(), + ); + await ticketToken.setRegistry(await bondingRegistry.getAddress()); + await bondingRegistry.setSlashingManager( + await slashingManager.getAddress(), + ); + await bondingRegistry.setRewardDistributor(enclaveAddress); + await slashingManager.setBondingRegistry( + await bondingRegistry.getAddress(), + ); + + // Mocks + const { mockComputeProvider } = await ignition.deploy( + mockComputeProviderModule, + ); + const { mockDecryptionVerifier: decryptionVerifier } = + await ignition.deploy(MockDecryptionVerifierModule); + const { mockE3Program: e3Program } = + await ignition.deploy(MockE3ProgramModule); + + await enclave.enableE3Program(await e3Program.getAddress()); + await enclave.setE3ProgramsParams([encodedE3ProgramParams]); + await enclave.setDecryptionVerifier( + encryptionSchemeId, + await decryptionVerifier.getAddress(), + ); + + // Operators + await licenseToken.setTransferRestriction(false); + for (const operator of [operator1, operator2, operator3]) { + await setupOperatorForSortition( + operator, + bondingRegistry, + licenseToken, + usdcToken, + ticketToken, + ciphernodeRegistryContract, + ); + } + await mine(1); + + // Mint USDC + const mintAmount = ethers.parseUnits("1000000", 6); + await usdcToken.mint(ownerAddress, mintAmount); + await usdcToken.mint(await notTheOwner.getAddress(), mintAmount); + + // Committee Thresholds: Micro [1,3], Small [2,5] + await enclave.setCommitteeThresholds(0, [1, 3]); + await enclave.setCommitteeThresholds(1, [2, 5]); + + // Build request params + const now = await time.latest(); + const request = { + committeeSize: 0, // Micro + inputWindow: [now + 10, now + inputWindowDuration] as [number, number], + e3Program: await e3Program.getAddress(), + e3ProgramParams: encodedE3ProgramParams, + computeProviderParams: abiCoder.encode( + ["address"], + [await decryptionVerifier.getAddress()], + ), + customParams: abiCoder.encode( + ["address"], + ["0x1234567890123456789012345678901234567890"], + ), + }; + + return { + owner, + notTheOwner, + operator1, + operator2, + operator3, + treasury, + enclave, + ciphernodeRegistryContract, + bondingRegistry, + licenseToken, + ticketToken, + usdcToken, + slashingManager, + e3RefundManager, + request, + mocks: { decryptionVerifier, e3Program, mockComputeProvider }, + }; + }; + + // Helper to make a request + const makeRequest = async ( + enclave: Enclave, + usdcToken: MockUSDC, + requestParams: Parameters[0], + signer?: Signer, + ) => { + const fee = await enclave.getE3Quote(requestParams); + const tokenContract = signer ? usdcToken.connect(signer) : usdcToken; + const enclaveContract = signer ? enclave.connect(signer) : enclave; + await tokenContract.approve(await enclave.getAddress(), fee); + return enclaveContract.request(requestParams); + }; + + // ────────────────────────────────────────────────────────────────────────── + // getE3Quote() — Parametric Fee Calculation + // ────────────────────────────────────────────────────────────────────────── + + describe("getE3Quote()", function () { + it("returns a fee based on BaseCosts, committee size, and duration", async function () { + const { enclave, request } = await loadFixture(setup); + + const fee = await enclave.getE3Quote(request); + // Fee must be > 0 with default baseCosts + expect(fee).to.be.gt(0); + }); + + it("computes fee correctly using the parametric formula", async function () { + const { enclave, request } = await loadFixture(setup); + + // Get the resolved threshold for Micro (committeeSize = 0) → [1, 3] + const n = 3n; // total committee + const m = 1n; // quorum + + // Get timeout config + const config = await enclave.getTimeoutConfig(); + const duration = + BigInt(request.inputWindow[1] - request.inputWindow[0]) + + config.dkgWindow + + config.computeWindow + + config.decryptionWindow; + + // Get pricing config + const pc = await enclave.getPricingConfig(); + + // Calculate expected fee + let baseFee = pc.keyGenPerNode * n; + if (n > 1n) baseFee += (pc.coordinationPerPair * n * (n - 1n)) / 2n; + baseFee += pc.availabilityPerNodePerSec * n * duration; + baseFee += pc.decryptionPerNode * m; + if (m > 1n) baseFee += (pc.coordinationPerPair * m * (m - 1n)) / 2n; + baseFee += pc.publicationBase; + + const marginBps = pc.marginBps; + const expectedFee = (baseFee * (10000n + BigInt(marginBps))) / 10000n; + + const actualFee = await enclave.getE3Quote(request); + expect(actualFee).to.equal(expectedFee); + }); + + it("fee increases with larger committee size", async function () { + const { enclave, request } = await loadFixture(setup); + + const microFee = await enclave.getE3Quote(request); + + // Build request with Small committee (larger) + const now = await time.latest(); + const smallRequest = { + ...request, + committeeSize: 1, // Small → [2, 5] + inputWindow: [now + 10, now + inputWindowDuration] as [number, number], + }; + const smallFee = await enclave.getE3Quote(smallRequest); + + expect(smallFee).to.be.gt(microFee); + }); + + it("fee increases with longer input window", async function () { + const { enclave, request } = await loadFixture(setup); + + const shortFee = await enclave.getE3Quote(request); + + const now = await time.latest(); + const longRequest = { + ...request, + inputWindow: [now + 10, now + 3600] as [number, number], // 1 hour vs 5min + }; + const longFee = await enclave.getE3Quote(longRequest); + + expect(longFee).to.be.gt(shortFee); + }); + + it("fee reflects margin changes", async function () { + const { enclave, request } = await loadFixture(setup); + + const fee10Pct = await enclave.getE3Quote(request); + + // Set margin to 20% + const pc = toPlainConfig(await enclave.getPricingConfig()); + await enclave.setPricingConfig({ ...pc, marginBps: 2000 }); + const fee20Pct = await enclave.getE3Quote(request); + + expect(fee20Pct).to.be.gt(fee10Pct); + + // Set margin to 0% + const pc2 = toPlainConfig(await enclave.getPricingConfig()); + await enclave.setPricingConfig({ ...pc2, marginBps: 0 }); + const feeZero = await enclave.getE3Quote(request); + + expect(feeZero).to.be.lt(fee10Pct); + }); + }); + + // ────────────────────────────────────────────────────────────────────────── + // setPricingConfig() — Governance + // ────────────────────────────────────────────────────────────────────────── + + describe("setPricingConfig()", function () { + it("reverts if not called by owner", async function () { + const { enclave, notTheOwner } = await loadFixture(setup); + await expect( + enclave.connect(notTheOwner).setPricingConfig(defaultPricingConfig), + ).to.be.revertedWithCustomError(enclave, "OwnableUnauthorizedAccount"); + }); + + it("updates config and emits event", async function () { + const { enclave } = await loadFixture(setup); + const newConfig = { + ...defaultPricingConfig, + keyGenPerNode: 200000n, + coordinationPerPair: 10000n, + availabilityPerNodePerSec: 40n, + decryptionPerNode: 300000n, + publicationBase: 1000000n, + publicationPerByte: 20n, + }; + + await expect(enclave.setPricingConfig(newConfig)).to.emit( + enclave, + "PricingConfigUpdated", + ); + + const stored = await enclave.getPricingConfig(); + expect(stored.keyGenPerNode).to.equal(200000n); + expect(stored.coordinationPerPair).to.equal(10000n); + expect(stored.availabilityPerNodePerSec).to.equal(40n); + expect(stored.decryptionPerNode).to.equal(300000n); + expect(stored.publicationBase).to.equal(1000000n); + expect(stored.publicationPerByte).to.equal(20n); + }); + + it("changes the fee returned by getE3Quote", async function () { + const { enclave, request } = await loadFixture(setup); + + const feeBefore = await enclave.getE3Quote(request); + + // Double base costs + await enclave.setPricingConfig({ + ...defaultPricingConfig, + keyGenPerNode: 200000n, + coordinationPerPair: 10000n, + availabilityPerNodePerSec: 40n, + decryptionPerNode: 300000n, + publicationBase: 1000000n, + publicationPerByte: 20n, + }); + + const feeAfter = await enclave.getE3Quote(request); + expect(feeAfter).to.be.gt(feeBefore); + }); + + it("reverts if margin exceeds 100%", async function () { + const { enclave } = await loadFixture(setup); + await expect( + enclave.setPricingConfig({ ...defaultPricingConfig, marginBps: 10001 }), + ).to.be.revertedWith("Margin exceeds 100%"); + }); + + it("allows setting margin to 0", async function () { + const { enclave } = await loadFixture(setup); + await enclave.setPricingConfig({ ...defaultPricingConfig, marginBps: 0 }); + const pc = await enclave.getPricingConfig(); + expect(pc.marginBps).to.equal(0); + }); + + it("reverts if protocolShareBps exceeds 100%", async function () { + const { enclave } = await loadFixture(setup); + await expect( + enclave.setPricingConfig({ + ...defaultPricingConfig, + protocolShareBps: 10001, + }), + ).to.be.revertedWith("Share exceeds 100%"); + }); + + it("reverts if minCommitteeSize < minThreshold", async function () { + const { enclave } = await loadFixture(setup); + await expect( + enclave.setPricingConfig({ + ...defaultPricingConfig, + minCommitteeSize: 2, + minThreshold: 5, + }), + ).to.be.revertedWith("Min size must be >= min threshold"); + }); + + it("enforces bounds on setCommitteeThresholds", async function () { + const { enclave } = await loadFixture(setup); + + // Set minimum bounds via pricing config + await enclave.setPricingConfig({ + ...defaultPricingConfig, + minCommitteeSize: 5, + minThreshold: 3, + }); + + // Should fail: committee size 4 < min 5 + await expect( + enclave.setCommitteeThresholds(0, [3, 4]), + ).to.be.revertedWith("Below min committee size"); + + // Should fail: threshold 2 < min 3 + await expect( + enclave.setCommitteeThresholds(0, [2, 6]), + ).to.be.revertedWith("Below min threshold"); + + // Should succeed: meets both minimums + await expect(enclave.setCommitteeThresholds(0, [3, 5])).to.not.be.revert( + ethers, + ); + }); + }); + + // ────────────────────────────────────────────────────────────────────────── + // Protocol Treasury Share on Reward Distribution + // ────────────────────────────────────────────────────────────────────────── + + describe("Protocol treasury share on success", function () { + it("sends 100% to CNs when protocolShareBps is 0 (default)", async function () { + const { + enclave, + usdcToken, + ciphernodeRegistryContract, + operator1, + operator2, + operator3, + mocks: { decryptionVerifier, e3Program }, + } = await loadFixture(setup); + + // Build a fresh request with current timestamps + const now = await time.latest(); + const freshRequest = { + committeeSize: 0, + inputWindow: [now + 100, now + inputWindowDuration + 100] as [ + number, + number, + ], + e3Program: await e3Program.getAddress(), + e3ProgramParams: encodedE3ProgramParams, + computeProviderParams: abiCoder.encode( + ["address"], + [await decryptionVerifier.getAddress()], + ), + customParams: abiCoder.encode( + ["address"], + ["0x1234567890123456789012345678901234567890"], + ), + }; + + // Make request with large approval to avoid fee mismatch + await usdcToken.approve(await enclave.getAddress(), ethers.MaxUint256); + await enclave.request(freshRequest); + const e3Id = 0; + const fee = await enclave.e3Payments(e3Id); + + // Setup committee + const nodes = [ + await operator1.getAddress(), + await operator2.getAddress(), + await operator3.getAddress(), + ]; + await setupAndPublishCommittee( + ciphernodeRegistryContract, + e3Id, + nodes, + "0x1234", + [operator1, operator2, operator3], + ); + + // Publish ciphertext + await time.increase(inputWindowDuration + 200); + await enclave.publishCiphertextOutput(e3Id, data, proof); + + // Record operator balances before distribution + const op1Before = await usdcToken.balanceOf(nodes[0]); + const op2Before = await usdcToken.balanceOf(nodes[1]); + const op3Before = await usdcToken.balanceOf(nodes[2]); + + // Publish plaintext (triggers _distributeRewards) + await enclave.publishPlaintextOutput(e3Id, data, proof); + + const op1After = await usdcToken.balanceOf(nodes[0]); + const op2After = await usdcToken.balanceOf(nodes[1]); + const op3After = await usdcToken.balanceOf(nodes[2]); + + // All fee distributed to operators (100%, no protocol share) + const totalDistributed = + op1After - op1Before + (op2After - op2Before) + (op3After - op3Before); + expect(totalDistributed).to.equal(fee); + }); + + it("splits fee between CNs and treasury when protocolShareBps > 0", async function () { + const { + enclave, + usdcToken, + ciphernodeRegistryContract, + treasury, + operator1, + operator2, + operator3, + mocks: { decryptionVerifier, e3Program }, + } = await loadFixture(setup); + + // Configure 20% protocol share + const treasuryAddr = await treasury.getAddress(); + await enclave.setPricingConfig({ + ...defaultPricingConfig, + protocolTreasury: treasuryAddr, + protocolShareBps: 2000, + }); + + // Build a fresh request with current timestamps + const now = await time.latest(); + const freshRequest = { + committeeSize: 0, + inputWindow: [now + 100, now + inputWindowDuration + 100] as [ + number, + number, + ], + e3Program: await e3Program.getAddress(), + e3ProgramParams: encodedE3ProgramParams, + computeProviderParams: abiCoder.encode( + ["address"], + [await decryptionVerifier.getAddress()], + ), + customParams: abiCoder.encode( + ["address"], + ["0x1234567890123456789012345678901234567890"], + ), + }; + + // Make request with large approval + await usdcToken.approve(await enclave.getAddress(), ethers.MaxUint256); + await enclave.request(freshRequest); + const e3Id = 0; + const fee = await enclave.e3Payments(e3Id); + + // Setup committee + const nodes = [ + await operator1.getAddress(), + await operator2.getAddress(), + await operator3.getAddress(), + ]; + await setupAndPublishCommittee( + ciphernodeRegistryContract, + e3Id, + nodes, + "0x1234", + [operator1, operator2, operator3], + ); + + // Publish outputs + await time.increase(inputWindowDuration + 200); + await enclave.publishCiphertextOutput(e3Id, data, proof); + + const treasuryBefore = await usdcToken.balanceOf(treasuryAddr); + const op1Before = await usdcToken.balanceOf(nodes[0]); + const op2Before = await usdcToken.balanceOf(nodes[1]); + const op3Before = await usdcToken.balanceOf(nodes[2]); + + await enclave.publishPlaintextOutput(e3Id, data, proof); + + const treasuryAfter = await usdcToken.balanceOf(treasuryAddr); + const op1After = await usdcToken.balanceOf(nodes[0]); + const op2After = await usdcToken.balanceOf(nodes[1]); + const op3After = await usdcToken.balanceOf(nodes[2]); + + const expectedProtocol = (fee * 2000n) / 10000n; + const expectedCN = fee - expectedProtocol; + const totalOpDistributed = + op1After - op1Before + (op2After - op2Before) + (op3After - op3Before); + + expect(treasuryAfter - treasuryBefore).to.equal(expectedProtocol); + expect(totalOpDistributed).to.equal(expectedCN); + }); + }); + + // ────────────────────────────────────────────────────────────────────────── + // Default Pricing Parameters (set in initialize) + // ────────────────────────────────────────────────────────────────────────── + + describe("Default pricing parameters", function () { + it("has correct default pricing config from initialize", async function () { + const { enclave } = await loadFixture(setup); + const pc = await enclave.getPricingConfig(); + expect(pc.keyGenPerNode).to.equal(100000); + expect(pc.coordinationPerPair).to.equal(5000); + expect(pc.availabilityPerNodePerSec).to.equal(20); + expect(pc.decryptionPerNode).to.equal(150000); + expect(pc.publicationBase).to.equal(500000); + expect(pc.publicationPerByte).to.equal(10); + expect(pc.marginBps).to.equal(1000); + expect(pc.protocolShareBps).to.equal(0); + expect(pc.protocolTreasury).to.equal(ethers.ZeroAddress); + expect(pc.minCommitteeSize).to.equal(0); + expect(pc.minThreshold).to.equal(0); + }); + }); + + // ────────────────────────────────────────────────────────────────────────── + // E3 Request with Parametric Pricing (end-to-end) + // ────────────────────────────────────────────────────────────────────────── + + describe("End-to-end request with parametric pricing", function () { + it("charges the computed fee and completes successfully", async function () { + const { + enclave, + usdcToken, + request, + ciphernodeRegistryContract, + operator1, + operator2, + operator3, + owner, + } = await loadFixture(setup); + + const fee = await enclave.getE3Quote(request); + const ownerAddr = await owner.getAddress(); + const balanceBefore = await usdcToken.balanceOf(ownerAddr); + + await usdcToken.approve(await enclave.getAddress(), fee); + await enclave.request(request); + + const balanceAfter = await usdcToken.balanceOf(ownerAddr); + expect(balanceBefore - balanceAfter).to.equal(fee); + }); + + it("reverts if USDC allowance is less than computed fee", async function () { + const { enclave, usdcToken, request } = await loadFixture(setup); + + // Approve only 1 unit + await usdcToken.approve(await enclave.getAddress(), 1); + + await expect(enclave.request(request)).to.be.revertedWithCustomError( + usdcToken, + "ERC20InsufficientAllowance", + ); + }); + }); +}); From a063b77f66f2d27b35d6ac3e906925550f5b6986 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Fri, 13 Mar 2026 23:44:09 +0500 Subject: [PATCH 02/11] fix: review comment --- .../IBondingRegistry.sol/IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IEnclave.sol/IEnclave.json | 17 +---------------- .../ISlashingManager.sol/ISlashingManager.json | 2 +- .../EnclaveTicketToken.json | 2 +- .../DkgPkVerifier.sol/DkgPkVerifier.json | 10 +++++----- .../DkgPkVerifier.sol/ZKTranscriptLib.json | 2 +- .../enclave-contracts/contracts/Enclave.sol | 1 - .../contracts/interfaces/IEnclave.sol | 1 - .../enclave-contracts/scripts/deployEnclave.ts | 1 - .../test/Pricing/Pricing.spec.ts | 6 ------ 11 files changed, 11 insertions(+), 35 deletions(-) diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 9de33c2762..d0d6a45ccf 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index 82976161e4..48e49c2c54 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -782,5 +782,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index b09285ebd7..9376b52327 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -457,11 +457,6 @@ "name": "publicationBase", "type": "uint256" }, - { - "internalType": "uint256", - "name": "publicationPerByte", - "type": "uint256" - }, { "internalType": "address", "name": "protocolTreasury", @@ -952,11 +947,6 @@ "name": "publicationBase", "type": "uint256" }, - { - "internalType": "uint256", - "name": "publicationPerByte", - "type": "uint256" - }, { "internalType": "address", "name": "protocolTreasury", @@ -1445,11 +1435,6 @@ "name": "publicationBase", "type": "uint256" }, - { - "internalType": "uint256", - "name": "publicationPerByte", - "type": "uint256" - }, { "internalType": "address", "name": "protocolTreasury", @@ -1523,5 +1508,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 21ebe50508..d4f18c82c5 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-75e601a049b1858741992bf4de30d4f4d471421f" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json b/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json index 09f0432af8..ae19e0285a 100644 --- a/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json +++ b/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json @@ -1223,5 +1223,5 @@ ] }, "inputSourceName": "project/contracts/token/EnclaveTicketToken.sol", - "buildInfoId": "solc-0_8_28-5311703a5d5fd8087d15f5c6957555cc4c2bf8c5" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.json b/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.json index 4f248bff8c..ea7c1f06e2 100644 --- a/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.json +++ b/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.json @@ -102,7 +102,7 @@ } }, "immutableReferences": { - "17861": [ + "35511": [ { "length": 32, "start": 91 @@ -152,13 +152,13 @@ "start": 11165 } ], - "17863": [ + "35513": [ { "length": 32, "start": 398 } ], - "17865": [ + "35515": [ { "length": 32, "start": 432 @@ -168,7 +168,7 @@ "start": 2303 } ], - "17867": [ + "35517": [ { "length": 32, "start": 3156 @@ -184,5 +184,5 @@ ] }, "inputSourceName": "project/contracts/verifier/DkgPkVerifier.sol", - "buildInfoId": "solc-0_8_28-608af4cb791a4cb30d57991d993af95c6fcfa77a" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.json b/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.json index 3aea254962..df9f7a1767 100644 --- a/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.json +++ b/packages/enclave-contracts/artifacts/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.json @@ -391,5 +391,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/verifier/DkgPkVerifier.sol", - "buildInfoId": "solc-0_8_28-608af4cb791a4cb30d57991d993af95c6fcfa77a" + "buildInfoId": "solc-0_8_28-f2a2dbad999ea25d3a1e9025e1883d5d78af79c3" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index aef63b9836..3ca1fa1cf9 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -288,7 +288,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { availabilityPerNodePerSec: 20, // 0.00002 USDC decryptionPerNode: 150000, // 0.15 USDC publicationBase: 500000, // 0.50 USDC - publicationPerByte: 10, // 0.00001 USDC protocolTreasury: address(0), marginBps: 1000, // 10% protocolShareBps: 0, diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index f180d6c3f4..fd8a6c9ebd 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -83,7 +83,6 @@ interface IEnclave { uint256 availabilityPerNodePerSec; uint256 decryptionPerNode; uint256 publicationBase; - uint256 publicationPerByte; address protocolTreasury; uint16 marginBps; uint16 protocolShareBps; diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index 0823efb0db..3be38fcdff 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -226,7 +226,6 @@ export const deployEnclave = async (withMocks?: boolean) => { availabilityPerNodePerSec: 20, // 0.00002 USDC decryptionPerNode: 150000, // 0.15 USDC publicationBase: 500000, // 0.50 USDC - publicationPerByte: 10, // 0.00001 USDC protocolTreasury: ownerAddress, marginBps: 1000, // 10% protocolShareBps: 2000, // 20% diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index 6d5ad7de30..22cbbf4fb9 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -49,7 +49,6 @@ describe("E3 Pricing", function () { availabilityPerNodePerSec: 20n, decryptionPerNode: 150000n, publicationBase: 500000n, - publicationPerByte: 10n, protocolTreasury: ethers.ZeroAddress, marginBps: 1000, protocolShareBps: 0, @@ -64,7 +63,6 @@ describe("E3 Pricing", function () { availabilityPerNodePerSec: pc.availabilityPerNodePerSec, decryptionPerNode: pc.decryptionPerNode, publicationBase: pc.publicationBase, - publicationPerByte: pc.publicationPerByte, protocolTreasury: pc.protocolTreasury, marginBps: pc.marginBps, protocolShareBps: pc.protocolShareBps, @@ -463,7 +461,6 @@ describe("E3 Pricing", function () { availabilityPerNodePerSec: 40n, decryptionPerNode: 300000n, publicationBase: 1000000n, - publicationPerByte: 20n, }; await expect(enclave.setPricingConfig(newConfig)).to.emit( @@ -477,7 +474,6 @@ describe("E3 Pricing", function () { expect(stored.availabilityPerNodePerSec).to.equal(40n); expect(stored.decryptionPerNode).to.equal(300000n); expect(stored.publicationBase).to.equal(1000000n); - expect(stored.publicationPerByte).to.equal(20n); }); it("changes the fee returned by getE3Quote", async function () { @@ -493,7 +489,6 @@ describe("E3 Pricing", function () { availabilityPerNodePerSec: 40n, decryptionPerNode: 300000n, publicationBase: 1000000n, - publicationPerByte: 20n, }); const feeAfter = await enclave.getE3Quote(request); @@ -739,7 +734,6 @@ describe("E3 Pricing", function () { expect(pc.availabilityPerNodePerSec).to.equal(20); expect(pc.decryptionPerNode).to.equal(150000); expect(pc.publicationBase).to.equal(500000); - expect(pc.publicationPerByte).to.equal(10); expect(pc.marginBps).to.equal(1000); expect(pc.protocolShareBps).to.equal(0); expect(pc.protocolTreasury).to.equal(ethers.ZeroAddress); From 1a5d4341d8c53294df285c72aaa97014f7df8f73 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Mon, 16 Mar 2026 05:32:37 +0500 Subject: [PATCH 03/11] fix: review comments --- packages/enclave-contracts/contracts/Enclave.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index b6fdb9b188..d06692d24b 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -1035,6 +1035,10 @@ contract Enclave is IEnclave, OwnableUpgradeable { function setPricingConfig(PricingConfig calldata config) public onlyOwner { require(config.marginBps <= BPS_BASE, "Margin exceeds 100%"); require(config.protocolShareBps <= BPS_BASE, "Share exceeds 100%"); + require( + config.protocolShareBps == 0 || config.protocolTreasury != address(0), + "Treasury required when protocol share > 0" + ); require( config.minCommitteeSize >= config.minThreshold, "Min size must be >= min threshold" @@ -1062,6 +1066,10 @@ contract Enclave is IEnclave, OwnableUpgradeable { uint32[2] memory threshold = committeeThresholds[ requestParams.committeeSize ]; + require( + threshold[1] > 0, + CommitteeSizeNotConfigured(requestParams.committeeSize) + ); uint256 n = uint256(threshold[1]); // total committee size uint256 m = uint256(threshold[0]); // quorum/decryption threshold From 7e9e0677b1b75b70eb8daabf7445e5d1fc7826df Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Sat, 21 Mar 2026 17:05:43 +0500 Subject: [PATCH 04/11] feat: update e3 Pricing --- .../contracts/Enclave.sol/Enclave.json | 235 +++++++++++++++++- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IEnclave.sol/IEnclave.json | 76 ++++-- .../ISlashingManager.json | 2 +- .../CiphernodeRegistryOwnable.json | 2 +- .../enclave-contracts/contracts/Enclave.sol | 25 +- .../contracts/interfaces/IEnclave.sol | 4 +- .../scripts/deployAndSave/mockPkVerifier.ts | 3 +- .../scripts/deployEnclave.ts | 4 +- .../enclave-contracts/scripts/deployMocks.ts | 3 +- .../test/Pricing/Pricing.spec.ts | 45 +++- 12 files changed, 349 insertions(+), 54 deletions(-) diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index be758b5471..5084afbc92 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -806,6 +806,81 @@ "name": "PlaintextOutputPublished", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "indexed": false, + "internalType": "struct IEnclave.PricingConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "PricingConfigUpdated", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1402,7 +1477,7 @@ } ], "internalType": "struct IEnclave.E3RequestParams", - "name": "", + "name": "requestParams", "type": "tuple" } ], @@ -1414,7 +1489,7 @@ "type": "uint256" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -1474,6 +1549,81 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getPricingConfig", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "internalType": "struct IEnclave.PricingConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -2075,6 +2225,81 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "coordinationPerPair", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availabilityPerNodePerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decryptionPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "publicationBase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, + { + "internalType": "address", + "name": "protocolTreasury", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "protocolShareBps", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minCommitteeSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "minThreshold", + "type": "uint32" + } + ], + "internalType": "struct IEnclave.PricingConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setPricingConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -2145,11 +2370,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b614949806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c80638e5ce3ad11610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b80639c8570c8116101315780639c8570c814610618578063ac3d2f421461062b578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b80638e5ce3ad1461058157806390173a41146105945780639117173c146105a957806392312386146105bc578063929a8faf146105cf57806399c6679d146105f0575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b5780637edcd7ab1461052e57806381476ec21461054157806385814243146105545780638da5cb5b146105675780638dcdd86b1461056f575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b31565b6107df565b005b6102da6102ea366004613be1565b610945565b6103176102fd366004613bfc565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c20565b60405180910390f35b61031761033b366004613bfc565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c47565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be1565b610a2d565b6102da61039e366004613c6f565b610ad2565b6103c56103b1366004613bfc565b5f908152600f602052604090205460ff1690565b6040516103249190613cb1565b6103e56103e0366004613bfc565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613cfd565b61041261040d366004613bfc565b610d10565b6040516103249190613eed565b61043e61042d366004613bfc565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613eff565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613bfc565b61100d565b6102da6104ab366004613be1565b61109c565b6104c36104be366004613f38565b61112f565b604051610324929190613f6f565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f87565b61194e565b6102da610516366004613fb8565b6119e6565b6102da610529366004613bfc565b611a6f565b61047a61053c366004614023565b611b6d565b6102da61054f36600461409a565b611d93565b600154610317906001600160a01b031681565b610317611e86565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b61059c611eb4565b60405161032491906140ba565b6102da6105b7366004613bfc565b611efa565b61059c6105ca366004613bfc565b6120a2565b6105e26105dd366004613bfc565b6120fb565b6040516103249291906140db565b6103176105fe366004613bfc565b5f908152601060205260409020546001600160a01b031690565b61047a610626366004614023565b612122565b610317610639366004613bfc565b5f908152600a60205260409020546001600160a01b031690565b6102da610661366004613f87565b6123ba565b6102da6106743660046140f1565b612451565b6102da610687366004613be1565b61253c565b6102da61069a36600461409a565b6125e3565b61047a6106ad366004613be1565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fb8565b6126c6565b6102da6106eb366004613bfc565b612779565b6107126106fe366004613bfc565b5f908152600d602052604090205460ff1690565b6040516103249190614129565b61043e61072d366004613f38565b6127b6565b6102da610740366004613be1565b6127c0565b6102da610753366004614137565b61285a565b600254610317906001600160a01b031681565b6102da610779366004613be1565b61296d565b6103c561078c366004613bfc565b6129a7565b6102da61079f366004613be1565b612b41565b6103176107b2366004613bfc565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be1565b612bd9565b5f6107e8612c68565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c92565b61089188612779565b61089a8c612b41565b6108a38b6127c0565b6108ac8a610945565b6108b589610a2d565b6108be87612ca3565b6108c7866123ba565b6108cf611e86565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d61296d565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612dd7565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612dd7565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c20565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c20565b60405180910390a150565b610ada612dd7565b610ae381612ca3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b319061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d9061416e565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610be99061416e565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c739061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f9061416e565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d18613826565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c89565b6003811115610d6657610d66613c89565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd89061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e049061416e565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e689061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e949061416e565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f309061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c9061416e565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612dd7565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612dd7565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c20565b5f611138613826565b5f60128161114960208701876141a0565b600381111561115a5761115a613c89565b600381111561116b5761116b613c89565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e96141b9565b602002015163ffffffff1611845f01602081019061120791906141a0565b906112265760405163286c068d60e11b815260040161099f91906141cd565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f91906112964260408901356141ef565b6112a09190614202565b6112aa9190614202565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be1565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be1565b906113325760405163295a6a6f60e11b815260040161099f9190613c20565b505f61133d866127b6565b60068054965090915085905f61135283614215565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f19190890135614202565b5f878152600e6020908152604090912060010191909155818652611417908801886141a0565b8560200190600381111561142d5761142d613c89565b9081600381111561144057611440613c89565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be1565b6001600160a01b031660a08601526114a3608088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb9088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261153890610100890190890161427c565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e09565b5f6115996080890160608a01613be1565b6001600160a01b031663fefd9a8b88846115b660808d018d61422d565b6115c360a08f018f61422d565b8f8060c001906115d3919061422d565b6040518963ffffffff1660e01b81526004016115f69897969594939291906142bf565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116369190614315565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c89565b0217905550604082015181600201556060820151816003019060026117309291906138a3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611775908261438b565b5060e0820151600882019061178a908261438b565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f2908261438b565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c90600401614440565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614485565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be1565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f6f565b60405180910390a2885f51602061491d5f395f51905f525f60016040516119279291906144a0565b60405180910390a250505050505050915091565b611943612dd7565b61194c5f612e76565b565b611956612dd7565b80515f5b818110156119aa57600b838281518110611976576119766141b9565b602002602001015160405161198b91906144bb565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da91906144d1565b60405180910390a15050565b6119ee612dd7565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f90614534565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c89565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614565565b5f828152600d60205260409020805460ff19166002179055601354611b079042614202565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061491d5f395f51905f5260016002604051611b619291906144a0565b60405180910390a25050565b5f5f611b7887610d10565b5f888152600d602052604090205490915060ff166004816006811115611ba057611ba0613c89565b1488600483909192611bc8576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611c2b576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f898152600860205260409020600d01611c48888a83614586565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611c8c92919061463a565b6040519081900381206001600160e01b031960e084901b168252611cb6918a908a90600401614649565b602060405180830381865afa158015611cd1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cf59190614485565b9350878785611d1957604051632f9f8ab960e01b815260040161099f92919061466b565b5050611d2489612ee6565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611d5692919061466b565b60405180910390a2885f51602061491d5f395f51905f5260046005604051611d7f9291906144a0565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611dbc5760405162461bcd60e51b815260040161099f90614534565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611dec57611dec613c89565b14611e1157836002826040516337e1404160e01b815260040161099f93929190614565565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061491d5f395f51905f5260026003604051611e789291906144a0565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611ed560405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f1f57611f1f613c89565b14611f5c5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611fae5760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611fc784613295565b5f858152601160205260409020546002549192506001600160a01b0390811691611ff49183911685613389565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061202a9088908790879087906004016146c1565b5f604051808303815f87803b158015612041575f5ffd5b505af1158015612053573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612093929190918252602082015260400190565b60405180910390a25050505050565b6120c360405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661211884826133b4565b9250925050915091565b5f5f61212d87610d10565b5f888152600d602052604090205490915060ff16600381600681111561215557612155613c89565b148860038390919261217d576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156121e1576040516308f3034360e31b81526004810192909252602482015260440161099f565b50506060830151602001518990428111156122185760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561224357604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161225592919061463a565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556015549091506122979042614202565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906122e4908d9085908c908c906004016146f8565b6020604051808303815f875af1158015612300573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123249190614485565b945088888661234857604051632f9f8ab960e01b815260040161099f92919061466b565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a60405161237c92919061466b565b60405180910390a2895f51602061491d5f395f51905f52600360046040516123a59291906144a0565b60405180910390a25050505095945050505050565b6123c2612dd7565b80515f5b81811015612421576001600b8483815181106123e4576123e46141b9565b60200260200101516040516123f991906144bb565b908152604051908190036020019020805491151560ff199092169190911790556001016123c6565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da91906144d1565b5f546001600160a01b031633148061247357506003546001600160a01b031633145b6124bf5760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124d55750600d60ff821611155b61251a5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b612538828260ff16600d81111561253357612533613c89565b61353c565b5050565b612544612dd7565b6001600160a01b03811661259a5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146126345760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561267e575f5ffd5b505af1158015612690573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126ce612dd7565b6001600160a01b038116158015906126ff57505f828152600960205260409020546001600160a01b03828116911614155b8290612721576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612781612dd7565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127c8612dd7565b6001600160a01b038116158015906127ee57506001546001600160a01b03828116911614155b819061280e576040516320252f0b60e01b815260040161099f9190613c20565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c20565b612862612dd7565b61286f602082018261472a565b63ffffffff16612885604083016020840161472a565b63ffffffff16101580156128aa57505f6128a2602083018361472a565b63ffffffff16115b6128ea5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290057612900613c89565b600381111561291157612911613c89565b815260208101919091526040015f2061292b9160026138e1565b5081600381111561293e5761293e613c89565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614743565b612975612dd7565b6001600160a01b03811661299e575f604051631e4fbdf760e01b815260040161099f9190613c20565b610ae381612e76565b5f818152600d602052604081205460ff16818160068111156129cb576129cb613c89565b036129f057826001826040516337e1404160e01b815260040161099f93929190614565565b6005816006811115612a0457612a04613c89565b03612a255760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3957612a39613c89565b03612a5a57604051633de16e3560e11b81526004810184905260240161099f565b5f612a6584836133b4565b9350905080612a8a57604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad357612ad3613c89565b0217905550835f51602061491d5f395f51905f52836006604051612af89291906144a0565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b32929190614781565b60405180910390a25050919050565b612b49612dd7565b6001600160a01b03811615801590612b6e57505f546001600160a01b03828116911614155b8190612b8e576040516375ac4eb760e11b815260040161099f9190613c20565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c20565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c155760405163b29d459560e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c20565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612c9a6136a4565b610ae3816136c9565b8035612ce65760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d325760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d815760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de0611e86565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c20565b6040516001600160a01b038481166024830152838116604483015260648201839052612e709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015612f2b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612f52919081019061479c565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003612ff0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590612fbc9088908890869060040161482b565b5f604051808303815f87803b158015612fd3575f5ffd5b505af1158015612fe5573d5f5f3e3d5ffd5b505050505050505050565b825f03613091575f858152601060205260409020546001600160a01b03168015613028576130286001600160a01b0383168285613389565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061305c9089908990879060040161482b565b5f604051808303815f87803b158015613073575f5ffd5b505af1158015613085573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156130aa576130aa6139d3565b6040519080825280602002602001820160405280156130d3578160200160208202803683370190505b5090505f6130e1858561485b565b90505f805b868110156131205782848281518110613101576131016141b9565b60209081029190910101526131168383614202565b91506001016130e6565b505f61312c82876141ef565b9050801561316957808461314160018a6141ef565b81518110613151576131516141b9565b602002602001018181516131659190614202565b9052505b600154613183906001600160a01b03878116911688613734565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906131b79088908c9089906004016148aa565b5f604051808303815f87803b1580156131ce575f5ffd5b505af11580156131e0573d5f5f3e3d5ffd5b50506001546131fe92506001600160a01b038881169250165f613734565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516132309291906148df565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326c908c908c908a9060040161482b565b5f604051808303815f87803b158015613283575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f818152600f602052604090205460609060ff16600181600d8111156132bd576132bd613c89565b14806132da5750600281600d8111156132d8576132d8613c89565b145b15613312575f5b60405190808252806020026020018201604052801561330a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa92505050801561337857506040513d5f823e601f3d908101601f19168201604052613375919081019061479c565b60015b613382575f6132e1565b9392505050565b6133af83846001600160a01b031663a9059cbb8585604051602401612e3e929190614903565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa15801561342e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134529190614315565b9050600185600681111561346857613468613c89565b14801561347457508042115b1561348757600180935093505050613535565b600285600681111561349b5761349b613c89565b1480156134a85750815142115b156134bc5760016003935093505050613535565b60038560068111156134d0576134d0613c89565b1480156134e05750816020015142115b156134f45760016006935093505050613535565b600485600681111561350857613508613c89565b1480156135185750816040015142115b1561352c576001600a935093505050613535565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561356057613560613c89565b0361358557826001826040516337e1404160e01b815260040161099f93929190614565565b600581600681111561359957613599613c89565b036135ba5760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135ce576135ce613c89565b036135ef57604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363857613638613c89565b0217905550825f51602061491d5f395f51905f5282600660405161365d9291906144a0565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051613697929190614781565b60405180910390a2505050565b6136ac6137c4565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b6129756136a4565b5f5f60205f8451602086015f885af1806136f0576040513d5f823e3d81fd5b50505f513d91508115613707578060011415613714565b6001600160a01b0384163b155b15612e705783604051635274afe760e01b815260040161099f9190613c20565b5f836001600160a01b031663095ea7b38484604051602401613757929190614903565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379084826137dd565b612e70576137ba84856001600160a01b031663095ea7b3865f604051602401612e3e929190614903565b612e7084826136d1565b5f6137cd612c68565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561381c5750811561380e578060011461381c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161384e61397d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d1579160200282015b828111156138d15782518255916020019190600101906138b6565b506138dd92915061399b565b5090565b6001830191839082156138d1579160200282015f5b8382111561394057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138f6565b80156139705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613940565b50506138dd92915061399b565b60405180604001604052806002906020820280368337509192915050565b5b808211156138dd575f815560010161399c565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a0f57613a0f6139d3565b604052919050565b5f6001600160401b03821115613a2f57613a2f6139d3565b5060051b60200190565b5f82601f830112613a48575f5ffd5b81356001600160401b03811115613a6157613a616139d3565b613a74601f8201601f19166020016139e7565b818152846020838601011115613a88575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab3575f5ffd5b8135613ac6613ac182613a17565b6139e7565b8082825260208201915060208360051b860101925085831115613ae7575f5ffd5b602085015b83811015613b275780356001600160401b03811115613b09575f5ffd5b613b18886020838a0101613a39565b84525060209283019201613aec565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b49575f5ffd5b8835613b54816139af565b97506020890135613b64816139af565b96506040890135613b74816139af565b95506060890135613b84816139af565b94506080890135613b94816139af565b935060a08901359250613baa8a60c08b016139c3565b91506101208901356001600160401b03811115613bc5575f5ffd5b613bd18b828c01613aa4565b9150509295985092959890939650565b5f60208284031215613bf1575f5ffd5b8135613382816139af565b5f60208284031215613c0c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c42575f5ffd5b919050565b5f5f60408385031215613c58575f5ffd5b613c6183613c34565b946020939093013593505050565b5f60608284031215613c7f575f5ffd5b61338283836139c3565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cad57613cad613c89565b9052565b60208101612c8c8284613c9d565b60048110613cad57613cad613c89565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d0d602082018f613cbf565b8c60408201528b6060820152613d26608082018c613c13565b6101c060a08201525f613d3d6101c083018c613ccf565b82810360c0840152613d4f818c613ccf565b9050613d5e60e084018b613c13565b613d6c61010084018a613c13565b8761012084015286610140840152828103610160840152613d8d8187613ccf565b915050613d9e610180830185613c13565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e70578151845260209384019390910190600101613dbd565b805182525f6020820151613df36020850182613cbf565b50604082015160408401526060820151613e106060850182613dba565b50608082015160a084015260a0820151613e2d60c0850182613c13565b5060c082015161020060e0850152613e49610200850182613ccf565b905060e0830151848203610100860152613e638282613ccf565b915050610100830151613e7a610120860182613c13565b50610120830151613e8f610140860182613c13565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec18282613ccf565b9150506101a0830151613ed86101c0860182613c13565b506101c08301518015156101e086015261330a565b602081525f6133826020830184613ddc565b5f60208284031215613f0f575f5ffd5b81356001600160401b03811115613f24575f5ffd5b613f3084828501613a39565b949350505050565b5f60208284031215613f48575f5ffd5b81356001600160401b03811115613f5d575f5ffd5b82016101008185031215613382575f5ffd5b828152604060208201525f613f306040830184613ddc565b5f60208284031215613f97575f5ffd5b81356001600160401b03811115613fac575f5ffd5b613f3084828501613aa4565b5f5f60408385031215613fc9575f5ffd5b823591506020830135613fdb816139af565b809150509250929050565b5f5f83601f840112613ff6575f5ffd5b5081356001600160401b0381111561400c575f5ffd5b602083019150836020828501011115613535575f5ffd5b5f5f5f5f5f60608688031215614037575f5ffd5b8535945060208601356001600160401b03811115614053575f5ffd5b61405f88828901613fe6565b90955093505060408601356001600160401b0381111561407d575f5ffd5b61408988828901613fe6565b969995985093965092949392505050565b5f5f604083850312156140ab575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c8c565b8215158152604081016133826020830184613c9d565b5f5f60408385031215614102575f5ffd5b82359150602083013560ff81168114613fdb575f5ffd5b60078110613cad57613cad613c89565b60208101612c8c8284614119565b5f5f60608385031215614148575f5ffd5b61415183613c34565b915083606084011115614162575f5ffd5b50926020919091019150565b600181811c9082168061418257607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f602082840312156141b0575f5ffd5b61338282613c34565b634e487b7160e01b5f52603260045260245ffd5b60208101612c8c8284613cbf565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c8c57612c8c6141db565b80820180821115612c8c57612c8c6141db565b5f60018201614226576142266141db565b5060010190565b5f5f8335601e19843603018112614242575f5ffd5b8301803591506001600160401b0382111561425b575f5ffd5b602001915036819003821315613535575f5ffd5b8015158114610ae3575f5ffd5b5f6020828403121561428c575f5ffd5b81356133828161426f565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6142de60a08301888a614297565b82810360608401526142f1818789614297565b90508281036080840152614306818587614297565b9b9a5050505050505050505050565b5f60208284031215614325575f5ffd5b5051919050565b601f8211156133af57805f5260205f20601f840160051c810160208510156143515750805b601f840160051c820191505b81811015614370575f815560010161435d565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b038111156143a4576143a46139d3565b6143b8816143b2845461416e565b8461432c565b6020601f8211600181146143e5575f83156143d35750848201515b6143dd8482614377565b855550614370565b5f84815260208120601f198516915b8281101561441457878501518255602094850194600190920191016143f4565b508482101561443157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561447a57815163ffffffff16835260209283019290910190600101614455565b505050949350505050565b5f60208284031215614495575f5ffd5b81516133828161426f565b604081016144ae8285614119565b6133826020830184614119565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561452857603f19878603018452614513858351613ccf565b945060209384019391909101906001016144f7565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016145796020830185614119565b613f306040830184614119565b6001600160401b0383111561459d5761459d6139d3565b6145b1836145ab835461416e565b8361432c565b5f601f8411600181146145dd575f85156145cb5750838201355b6145d58682614377565b845550614370565b5f83815260208120601f198716915b8281101561460c57868501358255602094850194600190920191016145ec565b5086821015614628575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f614662604083018486614297565b95945050505050565b602081525f613f30602083018486614297565b5f8151808452602084019350602083015f5b828110156146b75781516001600160a01b0316865260209586019590910190600101614690565b5093949350505050565b848152836020820152608060408201525f6146df608083018561467e565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f61381c606083018486614297565b803563ffffffff81168114613c42575f5ffd5b5f6020828403121561473a575f5ffd5b61338282614717565b6040810181835f5b60028110156147785763ffffffff61476283614717565b168352602092830192919091019060010161474b565b50505092915050565b6040810161478f8285614119565b6133826020830184613c9d565b5f602082840312156147ac575f5ffd5b81516001600160401b038111156147c1575f5ffd5b8201601f810184136147d1575f5ffd5b80516147df613ac182613a17565b8082825260208201915060208360051b850101925086831115614800575f5ffd5b6020840193505b8284101561381c57835161481a816139af565b825260209384019390910190614807565b838152606060208201525f614843606083018561467e565b905060018060a01b0383166040830152949350505050565b5f8261487557634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b828110156146b757815186526020958601959091019060010161488c565b6001600160a01b03841681526060602082018190525f906148cd9083018561467e565b828103604084015261381c818561487a565b604081525f6148f1604083018561467e565b8281036020840152614662818561487a565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c80638e5ce3ad11610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b80639c8570c8116101315780639c8570c814610618578063ac3d2f421461062b578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b80638e5ce3ad1461058157806390173a41146105945780639117173c146105a957806392312386146105bc578063929a8faf146105cf57806399c6679d146105f0575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b5780637edcd7ab1461052e57806381476ec21461054157806385814243146105545780638da5cb5b146105675780638dcdd86b1461056f575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b31565b6107df565b005b6102da6102ea366004613be1565b610945565b6103176102fd366004613bfc565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c20565b60405180910390f35b61031761033b366004613bfc565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c47565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be1565b610a2d565b6102da61039e366004613c6f565b610ad2565b6103c56103b1366004613bfc565b5f908152600f602052604090205460ff1690565b6040516103249190613cb1565b6103e56103e0366004613bfc565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613cfd565b61041261040d366004613bfc565b610d10565b6040516103249190613eed565b61043e61042d366004613bfc565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613eff565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613bfc565b61100d565b6102da6104ab366004613be1565b61109c565b6104c36104be366004613f38565b61112f565b604051610324929190613f6f565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f87565b61194e565b6102da610516366004613fb8565b6119e6565b6102da610529366004613bfc565b611a6f565b61047a61053c366004614023565b611b6d565b6102da61054f36600461409a565b611d93565b600154610317906001600160a01b031681565b610317611e86565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b61059c611eb4565b60405161032491906140ba565b6102da6105b7366004613bfc565b611efa565b61059c6105ca366004613bfc565b6120a2565b6105e26105dd366004613bfc565b6120fb565b6040516103249291906140db565b6103176105fe366004613bfc565b5f908152601060205260409020546001600160a01b031690565b61047a610626366004614023565b612122565b610317610639366004613bfc565b5f908152600a60205260409020546001600160a01b031690565b6102da610661366004613f87565b6123ba565b6102da6106743660046140f1565b612451565b6102da610687366004613be1565b61253c565b6102da61069a36600461409a565b6125e3565b61047a6106ad366004613be1565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fb8565b6126c6565b6102da6106eb366004613bfc565b612779565b6107126106fe366004613bfc565b5f908152600d602052604090205460ff1690565b6040516103249190614129565b61043e61072d366004613f38565b6127b6565b6102da610740366004613be1565b6127c0565b6102da610753366004614137565b61285a565b600254610317906001600160a01b031681565b6102da610779366004613be1565b61296d565b6103c561078c366004613bfc565b6129a7565b6102da61079f366004613be1565b612b41565b6103176107b2366004613bfc565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be1565b612bd9565b5f6107e8612c68565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c92565b61089188612779565b61089a8c612b41565b6108a38b6127c0565b6108ac8a610945565b6108b589610a2d565b6108be87612ca3565b6108c7866123ba565b6108cf611e86565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d61296d565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612dd7565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612dd7565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c20565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c20565b60405180910390a150565b610ada612dd7565b610ae381612ca3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b319061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d9061416e565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610be99061416e565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c739061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f9061416e565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d18613826565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c89565b6003811115610d6657610d66613c89565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd89061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e049061416e565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e689061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e949061416e565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f309061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c9061416e565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612dd7565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612dd7565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c20565b5f611138613826565b5f60128161114960208701876141a0565b600381111561115a5761115a613c89565b600381111561116b5761116b613c89565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e96141b9565b602002015163ffffffff1611845f01602081019061120791906141a0565b906112265760405163286c068d60e11b815260040161099f91906141cd565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f91906112964260408901356141ef565b6112a09190614202565b6112aa9190614202565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be1565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be1565b906113325760405163295a6a6f60e11b815260040161099f9190613c20565b505f61133d866127b6565b60068054965090915085905f61135283614215565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f19190890135614202565b5f878152600e6020908152604090912060010191909155818652611417908801886141a0565b8560200190600381111561142d5761142d613c89565b9081600381111561144057611440613c89565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be1565b6001600160a01b031660a08601526114a3608088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb9088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261153890610100890190890161427c565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e09565b5f6115996080890160608a01613be1565b6001600160a01b031663fefd9a8b88846115b660808d018d61422d565b6115c360a08f018f61422d565b8f8060c001906115d3919061422d565b6040518963ffffffff1660e01b81526004016115f69897969594939291906142bf565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116369190614315565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c89565b0217905550604082015181600201556060820151816003019060026117309291906138a3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611775908261438b565b5060e0820151600882019061178a908261438b565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f2908261438b565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c90600401614440565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614485565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be1565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f6f565b60405180910390a2885f51602061491d5f395f51905f525f60016040516119279291906144a0565b60405180910390a250505050505050915091565b611943612dd7565b61194c5f612e76565b565b611956612dd7565b80515f5b818110156119aa57600b838281518110611976576119766141b9565b602002602001015160405161198b91906144bb565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da91906144d1565b60405180910390a15050565b6119ee612dd7565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f90614534565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c89565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614565565b5f828152600d60205260409020805460ff19166002179055601354611b079042614202565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061491d5f395f51905f5260016002604051611b619291906144a0565b60405180910390a25050565b5f5f611b7887610d10565b5f888152600d602052604090205490915060ff166004816006811115611ba057611ba0613c89565b1488600483909192611bc8576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611c2b576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f898152600860205260409020600d01611c48888a83614586565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611c8c92919061463a565b6040519081900381206001600160e01b031960e084901b168252611cb6918a908a90600401614649565b602060405180830381865afa158015611cd1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cf59190614485565b9350878785611d1957604051632f9f8ab960e01b815260040161099f92919061466b565b5050611d2489612ee6565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611d5692919061466b565b60405180910390a2885f51602061491d5f395f51905f5260046005604051611d7f9291906144a0565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611dbc5760405162461bcd60e51b815260040161099f90614534565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611dec57611dec613c89565b14611e1157836002826040516337e1404160e01b815260040161099f93929190614565565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061491d5f395f51905f5260026003604051611e789291906144a0565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611ed560405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f1f57611f1f613c89565b14611f5c5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611fae5760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611fc784613295565b5f858152601160205260409020546002549192506001600160a01b0390811691611ff49183911685613389565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061202a9088908790879087906004016146c1565b5f604051808303815f87803b158015612041575f5ffd5b505af1158015612053573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612093929190918252602082015260400190565b60405180910390a25050505050565b6120c360405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661211884826133b4565b9250925050915091565b5f5f61212d87610d10565b5f888152600d602052604090205490915060ff16600381600681111561215557612155613c89565b148860038390919261217d576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156121e1576040516308f3034360e31b81526004810192909252602482015260440161099f565b50506060830151602001518990428111156122185760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561224357604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161225592919061463a565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556015549091506122979042614202565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906122e4908d9085908c908c906004016146f8565b6020604051808303815f875af1158015612300573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123249190614485565b945088888661234857604051632f9f8ab960e01b815260040161099f92919061466b565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a60405161237c92919061466b565b60405180910390a2895f51602061491d5f395f51905f52600360046040516123a59291906144a0565b60405180910390a25050505095945050505050565b6123c2612dd7565b80515f5b81811015612421576001600b8483815181106123e4576123e46141b9565b60200260200101516040516123f991906144bb565b908152604051908190036020019020805491151560ff199092169190911790556001016123c6565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da91906144d1565b5f546001600160a01b031633148061247357506003546001600160a01b031633145b6124bf5760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124d55750600d60ff821611155b61251a5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b612538828260ff16600d81111561253357612533613c89565b61353c565b5050565b612544612dd7565b6001600160a01b03811661259a5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146126345760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561267e575f5ffd5b505af1158015612690573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126ce612dd7565b6001600160a01b038116158015906126ff57505f828152600960205260409020546001600160a01b03828116911614155b8290612721576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612781612dd7565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127c8612dd7565b6001600160a01b038116158015906127ee57506001546001600160a01b03828116911614155b819061280e576040516320252f0b60e01b815260040161099f9190613c20565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c20565b612862612dd7565b61286f602082018261472a565b63ffffffff16612885604083016020840161472a565b63ffffffff16101580156128aa57505f6128a2602083018361472a565b63ffffffff16115b6128ea5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290057612900613c89565b600381111561291157612911613c89565b815260208101919091526040015f2061292b9160026138e1565b5081600381111561293e5761293e613c89565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614743565b612975612dd7565b6001600160a01b03811661299e575f604051631e4fbdf760e01b815260040161099f9190613c20565b610ae381612e76565b5f818152600d602052604081205460ff16818160068111156129cb576129cb613c89565b036129f057826001826040516337e1404160e01b815260040161099f93929190614565565b6005816006811115612a0457612a04613c89565b03612a255760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3957612a39613c89565b03612a5a57604051633de16e3560e11b81526004810184905260240161099f565b5f612a6584836133b4565b9350905080612a8a57604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad357612ad3613c89565b0217905550835f51602061491d5f395f51905f52836006604051612af89291906144a0565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b32929190614781565b60405180910390a25050919050565b612b49612dd7565b6001600160a01b03811615801590612b6e57505f546001600160a01b03828116911614155b8190612b8e576040516375ac4eb760e11b815260040161099f9190613c20565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c20565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c155760405163b29d459560e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c20565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612c9a6136a4565b610ae3816136c9565b8035612ce65760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d325760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d815760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de0611e86565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c20565b6040516001600160a01b038481166024830152838116604483015260648201839052612e709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015612f2b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612f52919081019061479c565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003612ff0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590612fbc9088908890869060040161482b565b5f604051808303815f87803b158015612fd3575f5ffd5b505af1158015612fe5573d5f5f3e3d5ffd5b505050505050505050565b825f03613091575f858152601060205260409020546001600160a01b03168015613028576130286001600160a01b0383168285613389565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061305c9089908990879060040161482b565b5f604051808303815f87803b158015613073575f5ffd5b505af1158015613085573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156130aa576130aa6139d3565b6040519080825280602002602001820160405280156130d3578160200160208202803683370190505b5090505f6130e1858561485b565b90505f805b868110156131205782848281518110613101576131016141b9565b60209081029190910101526131168383614202565b91506001016130e6565b505f61312c82876141ef565b9050801561316957808461314160018a6141ef565b81518110613151576131516141b9565b602002602001018181516131659190614202565b9052505b600154613183906001600160a01b03878116911688613734565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906131b79088908c9089906004016148aa565b5f604051808303815f87803b1580156131ce575f5ffd5b505af11580156131e0573d5f5f3e3d5ffd5b50506001546131fe92506001600160a01b038881169250165f613734565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516132309291906148df565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326c908c908c908a9060040161482b565b5f604051808303815f87803b158015613283575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f818152600f602052604090205460609060ff16600181600d8111156132bd576132bd613c89565b14806132da5750600281600d8111156132d8576132d8613c89565b145b15613312575f5b60405190808252806020026020018201604052801561330a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa92505050801561337857506040513d5f823e601f3d908101601f19168201604052613375919081019061479c565b60015b613382575f6132e1565b9392505050565b6133af83846001600160a01b031663a9059cbb8585604051602401612e3e929190614903565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa15801561342e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134529190614315565b9050600185600681111561346857613468613c89565b14801561347457508042115b1561348757600180935093505050613535565b600285600681111561349b5761349b613c89565b1480156134a85750815142115b156134bc5760016003935093505050613535565b60038560068111156134d0576134d0613c89565b1480156134e05750816020015142115b156134f45760016006935093505050613535565b600485600681111561350857613508613c89565b1480156135185750816040015142115b1561352c576001600a935093505050613535565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561356057613560613c89565b0361358557826001826040516337e1404160e01b815260040161099f93929190614565565b600581600681111561359957613599613c89565b036135ba5760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135ce576135ce613c89565b036135ef57604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363857613638613c89565b0217905550825f51602061491d5f395f51905f5282600660405161365d9291906144a0565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051613697929190614781565b60405180910390a2505050565b6136ac6137c4565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b6129756136a4565b5f5f60205f8451602086015f885af1806136f0576040513d5f823e3d81fd5b50505f513d91508115613707578060011415613714565b6001600160a01b0384163b155b15612e705783604051635274afe760e01b815260040161099f9190613c20565b5f836001600160a01b031663095ea7b38484604051602401613757929190614903565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379084826137dd565b612e70576137ba84856001600160a01b031663095ea7b3865f604051602401612e3e929190614903565b612e7084826136d1565b5f6137cd612c68565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561381c5750811561380e578060011461381c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161384e61397d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d1579160200282015b828111156138d15782518255916020019190600101906138b6565b506138dd92915061399b565b5090565b6001830191839082156138d1579160200282015f5b8382111561394057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138f6565b80156139705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613940565b50506138dd92915061399b565b60405180604001604052806002906020820280368337509192915050565b5b808211156138dd575f815560010161399c565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a0f57613a0f6139d3565b604052919050565b5f6001600160401b03821115613a2f57613a2f6139d3565b5060051b60200190565b5f82601f830112613a48575f5ffd5b81356001600160401b03811115613a6157613a616139d3565b613a74601f8201601f19166020016139e7565b818152846020838601011115613a88575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab3575f5ffd5b8135613ac6613ac182613a17565b6139e7565b8082825260208201915060208360051b860101925085831115613ae7575f5ffd5b602085015b83811015613b275780356001600160401b03811115613b09575f5ffd5b613b18886020838a0101613a39565b84525060209283019201613aec565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b49575f5ffd5b8835613b54816139af565b97506020890135613b64816139af565b96506040890135613b74816139af565b95506060890135613b84816139af565b94506080890135613b94816139af565b935060a08901359250613baa8a60c08b016139c3565b91506101208901356001600160401b03811115613bc5575f5ffd5b613bd18b828c01613aa4565b9150509295985092959890939650565b5f60208284031215613bf1575f5ffd5b8135613382816139af565b5f60208284031215613c0c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c42575f5ffd5b919050565b5f5f60408385031215613c58575f5ffd5b613c6183613c34565b946020939093013593505050565b5f60608284031215613c7f575f5ffd5b61338283836139c3565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cad57613cad613c89565b9052565b60208101612c8c8284613c9d565b60048110613cad57613cad613c89565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d0d602082018f613cbf565b8c60408201528b6060820152613d26608082018c613c13565b6101c060a08201525f613d3d6101c083018c613ccf565b82810360c0840152613d4f818c613ccf565b9050613d5e60e084018b613c13565b613d6c61010084018a613c13565b8761012084015286610140840152828103610160840152613d8d8187613ccf565b915050613d9e610180830185613c13565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e70578151845260209384019390910190600101613dbd565b805182525f6020820151613df36020850182613cbf565b50604082015160408401526060820151613e106060850182613dba565b50608082015160a084015260a0820151613e2d60c0850182613c13565b5060c082015161020060e0850152613e49610200850182613ccf565b905060e0830151848203610100860152613e638282613ccf565b915050610100830151613e7a610120860182613c13565b50610120830151613e8f610140860182613c13565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec18282613ccf565b9150506101a0830151613ed86101c0860182613c13565b506101c08301518015156101e086015261330a565b602081525f6133826020830184613ddc565b5f60208284031215613f0f575f5ffd5b81356001600160401b03811115613f24575f5ffd5b613f3084828501613a39565b949350505050565b5f60208284031215613f48575f5ffd5b81356001600160401b03811115613f5d575f5ffd5b82016101008185031215613382575f5ffd5b828152604060208201525f613f306040830184613ddc565b5f60208284031215613f97575f5ffd5b81356001600160401b03811115613fac575f5ffd5b613f3084828501613aa4565b5f5f60408385031215613fc9575f5ffd5b823591506020830135613fdb816139af565b809150509250929050565b5f5f83601f840112613ff6575f5ffd5b5081356001600160401b0381111561400c575f5ffd5b602083019150836020828501011115613535575f5ffd5b5f5f5f5f5f60608688031215614037575f5ffd5b8535945060208601356001600160401b03811115614053575f5ffd5b61405f88828901613fe6565b90955093505060408601356001600160401b0381111561407d575f5ffd5b61408988828901613fe6565b969995985093965092949392505050565b5f5f604083850312156140ab575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c8c565b8215158152604081016133826020830184613c9d565b5f5f60408385031215614102575f5ffd5b82359150602083013560ff81168114613fdb575f5ffd5b60078110613cad57613cad613c89565b60208101612c8c8284614119565b5f5f60608385031215614148575f5ffd5b61415183613c34565b915083606084011115614162575f5ffd5b50926020919091019150565b600181811c9082168061418257607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f602082840312156141b0575f5ffd5b61338282613c34565b634e487b7160e01b5f52603260045260245ffd5b60208101612c8c8284613cbf565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c8c57612c8c6141db565b80820180821115612c8c57612c8c6141db565b5f60018201614226576142266141db565b5060010190565b5f5f8335601e19843603018112614242575f5ffd5b8301803591506001600160401b0382111561425b575f5ffd5b602001915036819003821315613535575f5ffd5b8015158114610ae3575f5ffd5b5f6020828403121561428c575f5ffd5b81356133828161426f565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6142de60a08301888a614297565b82810360608401526142f1818789614297565b90508281036080840152614306818587614297565b9b9a5050505050505050505050565b5f60208284031215614325575f5ffd5b5051919050565b601f8211156133af57805f5260205f20601f840160051c810160208510156143515750805b601f840160051c820191505b81811015614370575f815560010161435d565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b038111156143a4576143a46139d3565b6143b8816143b2845461416e565b8461432c565b6020601f8211600181146143e5575f83156143d35750848201515b6143dd8482614377565b855550614370565b5f84815260208120601f198516915b8281101561441457878501518255602094850194600190920191016143f4565b508482101561443157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561447a57815163ffffffff16835260209283019290910190600101614455565b505050949350505050565b5f60208284031215614495575f5ffd5b81516133828161426f565b604081016144ae8285614119565b6133826020830184614119565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561452857603f19878603018452614513858351613ccf565b945060209384019391909101906001016144f7565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016145796020830185614119565b613f306040830184614119565b6001600160401b0383111561459d5761459d6139d3565b6145b1836145ab835461416e565b8361432c565b5f601f8411600181146145dd575f85156145cb5750838201355b6145d58682614377565b845550614370565b5f83815260208120601f198716915b8281101561460c57868501358255602094850194600190920191016145ec565b5086821015614628575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f614662604083018486614297565b95945050505050565b602081525f613f30602083018486614297565b5f8151808452602084019350602083015f5b828110156146b75781516001600160a01b0316865260209586019590910190600101614690565b5093949350505050565b848152836020820152608060408201525f6146df608083018561467e565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f61381c606083018486614297565b803563ffffffff81168114613c42575f5ffd5b5f6020828403121561473a575f5ffd5b61338282614717565b6040810181835f5b60028110156147785763ffffffff61476283614717565b168352602092830192919091019060010161474b565b50505092915050565b6040810161478f8285614119565b6133826020830184613c9d565b5f602082840312156147ac575f5ffd5b81516001600160401b038111156147c1575f5ffd5b8201601f810184136147d1575f5ffd5b80516147df613ac182613a17565b8082825260208201915060208360051b850101925086831115614800575f5ffd5b6020840193505b8284101561381c57835161481a816139af565b825260209384019390910190614807565b838152606060208201525f614843606083018561467e565b905060018060a01b0383166040830152949350505050565b5f8261487557634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b828110156146b757815186526020958601959091019060010161488c565b6001600160a01b03841681526060602082018190525f906148cd9083018561467e565b828103604084015261381c818561487a565b604081525f6148f1604083018561467e565b8281036020840152614662818561487a565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615689806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c806390173a4111610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a0d4664f1161013c578063a0d4664f14610641578063a87f4ab914610654578063ac3d2f4214610669578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b806390173a41146105aa5780639117173c146105bf57806392312386146105d2578063929a8faf146105e557806399c6679d146106065780639c8570c81461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d74146105315780637edcd7ab1461054457806381476ec214610557578063858142431461056a5780638da5cb5b1461057d5780638dcdd86b146105855780638e5ce3ad14610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461451d565b61081d565b005b6102f06103003660046145cd565b610a2a565b61032d6103133660046145e8565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061460c565b60405180910390f35b61032d6103513660046145e8565b60096020525f90815260409020546001600160a01b031681565b61037e61037936600461462e565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a13660046145cd565b610b12565b6102f06103b4366004614656565b610bb7565b6103db6103c73660046145e8565b5f908152600f602052604090205460ff1690565b60405161033a9190614698565b6103fb6103f63660046145e8565b610bcb565b60405161033a9e9d9c9b9a999897969594939291906146e4565b6104286104233660046145e8565b610df5565b60405161033a91906148d4565b6104546104433660046145e8565b600c6020525f908152604090205481565b60405190815260200161033a565b6104906104703660046148e6565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046145e8565b6110f2565b6102f06104c13660046145cd565b611181565b6104d96104d436600461491f565b611214565b60405161033a929190614956565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a20565b6102f061051936600461496e565b611a33565b6102f061052c36600461499f565b611acb565b6102f061053f3660046145e8565b611b54565b610490610552366004614a0a565b611c52565b6102f0610565366004614a81565b611e78565b60015461032d906001600160a01b031681565b61032d611f6b565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b6105b2611f99565b60405161033a9190614aa1565b6102f06105cd3660046145e8565b611fdf565b6105b26105e03660046145e8565b612187565b6105f86105f33660046145e8565b6121e0565b60405161033a929190614ac2565b61032d6106143660046145e8565b5f908152601060205260409020546001600160a01b031690565b61049061063c366004614a0a565b612207565b6102f061064f366004614ad8565b61249f565b61065c6126c0565b60405161033a9190614af2565b61032d6106773660046145e8565b5f908152600a60205260409020546001600160a01b031690565b6102f061069f36600461496e565b6127d0565b6102f06106b2366004614bb7565b612867565b6102f06106c53660046145cd565b612952565b6102f06106d8366004614a81565b6129f9565b6104906106eb3660046145cd565b60076020525f908152604090205460ff1681565b61045460065481565b6102f061071636600461499f565b612adc565b6102f06107293660046145e8565b612b8f565b61075061073c3660046145e8565b5f908152600d602052604090205460ff1690565b60405161033a9190614bef565b61045461076b36600461491f565b612bcc565b6102f061077e3660046145cd565b612f71565b6102f0610791366004614bfd565b61300b565b60025461032d906001600160a01b031681565b6102f06107b73660046145cd565b6132a8565b6103db6107ca3660046145e8565b6132e2565b6102f06107dd3660046145cd565b61347c565b61032d6107f03660046145e8565b600a6020525f90815260409020546001600160a01b031681565b6102f06108183660046145cd565b613514565b5f6108266135a3565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336135cd565b6108cf88612b8f565b6108d88c61347c565b6108e18b612f71565b6108ea8a610a2a565b6108f389610b12565b6108fc876135de565b610905866127d0565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601694909455601792909255601894909455601993909355601a92909255601b91909155601c55607d60a31b601d556109b4611f6b565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6132a8565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613712565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613712565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a84919061460c565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac90839061460c565b60405180910390a150565b610bbf613712565b610bc8816135de565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614c34565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614c34565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614c34565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614202565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a614670565b6003811115610e4b57610e4b614670565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614c34565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614c34565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614c34565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613712565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613712565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac90839061460c565b5f61121d614202565b5f60128161122e6020870187614c66565b600381111561123f5761123f614670565b600381111561125057611250614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614c7f565b602002015163ffffffff1611845f0160208101906112ec9190614c66565b9061130b5760405163286c068d60e11b8152600401610a849190614c93565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506015546014545f919061137b426040890135614cb5565b6113859190614cc8565b61138f9190614cc8565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc60808801606089016145cd565b6001600160a01b0316815260208101919091526040015f205460ff166113f860808701606088016145cd565b906114175760405163295a6a6f60e11b8152600401610a84919061460c565b505f61142286612bcc565b60068054965090915085905f61143783614cdb565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506114d69190890135614cc8565b5f878152600e60209081526040909120600101919091558186526114fc90880188614c66565b8560200190600381111561151257611512614670565b9081600381111561152557611525614670565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261156d90608089019089016145cd565b6001600160a01b031660a08601526115886080880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526115d090880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261161d906101008901908901614d42565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a0860181905260045461166d916001600160a01b03909116903085613744565b5f61167e6080890160608a016145cd565b6001600160a01b031663fefd9a8b888461169b60808d018d614cf3565b6116a860a08f018f614cf3565b8f8060c001906116b89190614cf3565b6040518963ffffffff1660e01b81526004016116db989796959493929190614d85565b6020604051808303815f875af11580156116f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061171b9190614ddb565b5f818152600960205260409020549091506001600160a01b03168181611757576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b03168281611791576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156117ef576117ef614670565b02179055506040820151816002015560608201518160030190600261181592919061427f565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c0820151600782019061185a9082614e51565b5060e0820151600882019061186f9082614e51565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906118d79082614e51565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b9061193d908c9088908c90600401614f06565b6020604051808303815f875af1158015611959573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197d9190614f4b565b61199a57604051630d8dbe2560e01b815260040160405180910390fd5b6119aa60808b0160608c016145cd565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516119e4929190614956565b60405180910390a2885f51602061565d5f395f51905f525f6001604051611a0c929190614f66565b60405180910390a250505050505050915091565b611a28613712565b611a315f6137b1565b565b611a3b613712565b80515f5b81811015611a8f57600b838281518110611a5b57611a5b614c7f565b6020026020010151604051611a709190614f81565b908152604051908190036020019020805460ff19169055600101611a3f565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611abf9190614f97565b60405180910390a15050565b611ad3613712565b6001600160a01b03811615801590611b0457505f828152600a60205260409020546001600160a01b03828116911614155b8290611b26576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610a8490614ffa565b5f818152600d602052604090205460ff166001816006811115611ba257611ba2614670565b14611bc757816001826040516337e1404160e01b8152600401610a849392919061502b565b5f828152600d60205260409020805460ff19166002179055601354611bec9042614cc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061565d5f395f51905f5260016002604051611c46929190614f66565b60405180910390a25050565b5f5f611c5d87610df5565b5f888152600d602052604090205490915060ff166004816006811115611c8557611c85614670565b1488600483909192611cad576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611d10576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f898152600860205260409020600d01611d2d888a8361504c565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611d71929190615100565b6040519081900381206001600160e01b031960e084901b168252611d9b918a908a9060040161510f565b602060405180830381865afa158015611db6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dda9190614f4b565b9350878785611dfe57604051632f9f8ab960e01b8152600401610a84929190615131565b5050611e0989613821565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611e3b929190615131565b60405180910390a2885f51602061565d5f395f51905f5260046005604051611e64929190614f66565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611ea15760405162461bcd60e51b8152600401610a8490614ffa565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ed157611ed1614670565b14611ef657836002826040516337e1404160e01b8152600401610a849392919061502b565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061565d5f395f51905f5260026003604051611f5d929190614f66565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611fba60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff16600681600681111561200457612004614670565b146120415760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c6020526040902054806120935760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c602052604081208190556120ac84613c7e565b5f858152601160205260409020546002549192506001600160a01b03908116916120d99183911685613d72565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061210f908890879087908790600401615187565b5f604051808303815f87803b158015612126575f5ffd5b505af1158015612138573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612178929190918252602082015260400190565b60405180910390a25050505050565b6121a860405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121fd8482613d9d565b9250925050915091565b5f5f61221287610df5565b5f888152600d602052604090205490915060ff16600381600681111561223a5761223a614670565b1488600383909192612262576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156122c6576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156122fd5760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561232857604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161233a929190615100565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061237c9042614cc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906123c9908d9085908c908c906004016151be565b6020604051808303815f875af11580156123e5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124099190614f4b565b945088888661242d57604051632f9f8ab960e01b8152600401610a84929190615131565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051612461929190615131565b60405180910390a2895f51602061565d5f395f51905f526003600460405161248a929190614f66565b60405180910390a25050505095945050505050565b6124a7613712565b6127106124bc610120830161010084016151f7565b61ffff1611156125045760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b612710612519610140830161012084016151f7565b61ffff1611156125605760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612572610140820161012083016151f7565b61ffff16158061259b57505f61258f610100830160e084016145cd565b6001600160a01b031614155b6125f95760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61260b6101808201610160830161522e565b63ffffffff166126236101608301610140840161522e565b63ffffffff1610156126815760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b80601661268e828261526d565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906153a5565b6127356040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b6127d8613712565b80515f5b81811015612837576001600b8483815181106127fa576127fa614c7f565b602002602001015160405161280f9190614f81565b908152604051908190036020019020805491151560ff199092169190911790556001016127dc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611abf9190614f97565b5f546001600160a01b031633148061288957506003546001600160a01b031633145b6128d55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff161180156128eb5750600d60ff821611155b6129305760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b61294e828260ff16600d81111561294957612949614670565b613f25565b5050565b61295a613712565b6001600160a01b0381166129b05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a4a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612a94575f5ffd5b505af1158015612aa6573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c4691815260200190565b612ae4613712565b6001600160a01b03811615801590612b1557505f828152600960205260409020546001600160a01b03828116911614155b8290612b37576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611abf565b612b97613712565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612bde6020860186614c66565b6003811115612bef57612bef614670565b6003811115612c0057612c00614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c27579050505050505090505f81600160028110612c7e57612c7e614c7f565b602002015163ffffffff1611835f016020810190612c9c9190614c66565b90612cbb5760405163286c068d60e11b8152600401610a849190614c93565b5060208181015182516040805161018081018252601654815260175481860152601854818301526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b909104811661016083015260155460145460135496831697929095169592945f94919390929091612d84918c0135908c0135614cb5565b612d8e9190614cc8565b612d989190614cc8565b612da29190614cc8565b90505f612db0600186614cb5565b612dbb90600261546a565b612dc690600261546a565b612dd1906006614cc8565b90505f85845f0151612de3919061546a565b905081868560200151612df6919061546a565b612e00919061546a565b612e0a9082614cc8565b90506001861115612e52576002612e22600188614cb5565b612e2c908861546a565b8560400151612e3b919061546a565b612e459190615481565b612e4f9082614cc8565b90505b81868560c00151612e63919061546a565b612e6d919061546a565b612e779082614cc8565b905082868560600151612e8a919061546a565b612e94919061546a565b612e9e9082614cc8565b9050848460800151612eb0919061546a565b612eba9082614cc8565b90506001851115612f02576002612ed2600187614cb5565b612edc908761546a565b8560400151612eeb919061546a565b612ef59190615481565b612eff9082614cc8565b90505b60a0840151612f119082614cc8565b61010085015190915061271090612f2c9061ffff1682614cc8565b612f36908361546a565b612f409190615481565b97508780612f6457604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b612f79613712565b6001600160a01b03811615801590612f9f57506001546001600160a01b03828116911614155b8190612fbf576040516320252f0b60e01b8152600401610a84919061460c565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac90839061460c565b613013613712565b613020602082018261522e565b63ffffffff16613036604083016020840161522e565b63ffffffff161015801561305b57505f613053602083018361522e565b63ffffffff16115b61309b5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156131a45761014081015163ffffffff16613155604084016020850161522e565b63ffffffff1610156131a45760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff16156132185761016081015163ffffffff166131ce602084018461522e565b63ffffffff1610156132185760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f85600381111561322e5761322e614670565b600381111561323f5761323f614670565b815260208101919091526040015f206132599160026142bd565b5082600381111561326c5761326c614670565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161329b91906154a0565b60405180910390a2505050565b6132b0613712565b6001600160a01b0381166132d9575f604051631e4fbdf760e01b8152600401610a84919061460c565b610bc8816137b1565b5f818152600d602052604081205460ff168181600681111561330657613306614670565b0361332b57826001826040516337e1404160e01b8152600401610a849392919061502b565b600581600681111561333f5761333f614670565b036133605760405163462c7bed60e01b815260048101849052602401610a84565b600681600681111561337457613374614670565b0361339557604051633de16e3560e11b815260048101849052602401610a84565b5f6133a08483613d9d565b93509050806133c557604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561340e5761340e614670565b0217905550835f51602061565d5f395f51905f52836006604051613433929190614f66565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161346d9291906154e0565b60405180910390a25050919050565b613484613712565b6001600160a01b038116158015906134a957505f546001600160a01b03828116911614155b81906134c9576040516375ac4eb760e11b8152600401610a84919061460c565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac90839061460c565b6001600160a01b0381165f90815260076020526040902054819060ff16156135505760405163b29d459560e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac90839061460c565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6135d5614080565b610bc8816140a5565b80356136215760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f81602001351161366d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116136bc5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b3361371b611f6b565b6001600160a01b031614611a31573360405163118cdaa760e01b8152600401610a84919061460c565b6040516001600160a01b0384811660248301528381166044830152606482018390526137ab9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506140ad565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613866573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261388d91908101906154fb565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361392b576002546040516341489f1560e01b81526001600160a01b03909116906341489f15906138f79088908890869060040161558a565b5f604051808303815f87803b15801561390e575f5ffd5b505af1158015613920573d5f5f3e3d5ffd5b505050505050505050565b825f036139cc575f858152601060205260409020546001600160a01b03168015613963576139636001600160a01b0383168285613d72565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906139979089908990879060040161558a565b5f604051808303815f87803b1580156139ae575f5ffd5b505af11580156139c0573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156139e5576139e56143bf565b604051908082528060200260200182016040528015613a0e578160200160208202803683370190505b50601d549091505f9061ffff600160b01b820416906001600160a01b03168115801590613a4357506001600160a01b03811615155b15613a7f57612710613a5961ffff84168861546a565b613a639190615481565b92508215613a7f57613a7f6001600160a01b0386168285613d72565b5f613a8a8488614cb5565b90505f613a978983615481565b90505f805b8a811015613ad65782888281518110613ab757613ab7614c7f565b6020908102919091010152613acc8383614cc8565b9150600101613a9c565b505f613ae28285614cb5565b90508015613b1f578088613af760018e614cb5565b81518110613b0757613b07614c7f565b60200260200101818151613b1b9190614cc8565b9052505b600154613b39906001600160a01b038b8116911686614110565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e8b6040518463ffffffff1660e01b8152600401613b7d939291906155ea565b5f604051808303815f87803b158015613b94575f5ffd5b505af1158015613ba6573d5f5f3e3d5ffd5b5050600154613bc492506001600160a01b038c81169250165f614110565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8a604051613bf692919061561f565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613c429392919061558a565b5f604051808303815f87803b158015613c59575f5ffd5b505af1158015613c6b573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613ca657613ca6614670565b1480613cc35750600281600d811115613cc157613cc1614670565b145b15613cfb575f5b604051908082528060200260200182016040528015613cf3578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613d6157506040513d5f823e601f3d908101601f19168201604052613d5e91908101906154fb565b60015b613d6b575f613cca565b9392505050565b613d9883846001600160a01b031663a9059cbb8585604051602401613779929190615643565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613e17573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e3b9190614ddb565b90506001856006811115613e5157613e51614670565b148015613e5d57508042115b15613e7057600180935093505050613f1e565b6002856006811115613e8457613e84614670565b148015613e915750815142115b15613ea55760016003935093505050613f1e565b6003856006811115613eb957613eb9614670565b148015613ec95750816020015142115b15613edd5760016006935093505050613f1e565b6004856006811115613ef157613ef1614670565b148015613f015750816040015142115b15613f15576001600a935093505050613f1e565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff1690816006811115613f4957613f49614670565b03613f6e57826001826040516337e1404160e01b8152600401610a849392919061502b565b6005816006811115613f8257613f82614670565b03613fa35760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613fb757613fb7614670565b03613fd857604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561402157614021614670565b0217905550825f51602061565d5f395f51905f52826006604051614046929190614f66565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161329b9291906154e0565b6140886141a0565b611a3157604051631afcd79f60e31b815260040160405180910390fd5b6132b0614080565b5f5f60205f8451602086015f885af1806140cc576040513d5f823e3d81fd5b50505f513d915081156140e35780600114156140f0565b6001600160a01b0384163b155b156137ab5783604051635274afe760e01b8152600401610a84919061460c565b5f836001600160a01b031663095ea7b38484604051602401614133929190615643565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061416c84826141b9565b6137ab5761419684856001600160a01b031663095ea7b3865f604051602401613779929190615643565b6137ab84826140ad565b5f6141a96135a3565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156141f8575081156141ea57806001146141f8565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161422a614359565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156142ad579160200282015b828111156142ad578251825591602001919060010190614292565b506142b9929150614377565b5090565b6001830191839082156142ad579160200282015f5b8382111561431c57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026142d2565b801561434c5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261431c565b50506142b9929150614377565b60405180604001604052806002906020820280368337509192915050565b5b808211156142b9575f8155600101614378565b6001600160a01b0381168114610bc8575f5ffd5b80356143aa8161438b565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156143fb576143fb6143bf565b604052919050565b5f6001600160401b0382111561441b5761441b6143bf565b5060051b60200190565b5f82601f830112614434575f5ffd5b81356001600160401b0381111561444d5761444d6143bf565b614460601f8201601f19166020016143d3565b818152846020838601011115614474575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f83011261449f575f5ffd5b81356144b26144ad82614403565b6143d3565b8082825260208201915060208360051b8601019250858311156144d3575f5ffd5b602085015b838110156145135780356001600160401b038111156144f5575f5ffd5b614504886020838a0101614425565b845250602092830192016144d8565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614535575f5ffd5b88356145408161438b565b975060208901356145508161438b565b965060408901356145608161438b565b955060608901356145708161438b565b945060808901356145808161438b565b935060a089013592506145968a60c08b016143af565b91506101208901356001600160401b038111156145b1575f5ffd5b6145bd8b828c01614490565b9150509295985092959890939650565b5f602082840312156145dd575f5ffd5b8135613d6b8161438b565b5f602082840312156145f8575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106143aa575f5ffd5b5f5f6040838503121561463f575f5ffd5b61464883614620565b946020939093013593505050565b5f60608284031215614666575f5ffd5b613d6b83836143af565b634e487b7160e01b5f52602160045260245ffd5b600e811061469457614694614670565b9052565b602081016135c78284614684565b6004811061469457614694614670565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526146f4602082018f6146a6565b8c60408201528b606082015261470d608082018c6145ff565b6101c060a08201525f6147246101c083018c6146b6565b82810360c0840152614736818c6146b6565b905061474560e084018b6145ff565b61475361010084018a6145ff565b876101208401528661014084015282810361016084015261477481876146b6565b9150506147856101808301856145ff565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156137ab5781518452602093840193909101906001016147a4565b805182525f60208201516147da60208501826146a6565b506040820151604084015260608201516147f760608501826147a1565b50608082015160a084015260a082015161481460c08501826145ff565b5060c082015161020060e08501526148306102008501826146b6565b905060e083015184820361010086015261484a82826146b6565b9150506101008301516148616101208601826145ff565b506101208301516148766101408601826145ff565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148a882826146b6565b9150506101a08301516148bf6101c08601826145ff565b506101c08301518015156101e0860152613cf3565b602081525f613d6b60208301846147c3565b5f602082840312156148f6575f5ffd5b81356001600160401b0381111561490b575f5ffd5b61491784828501614425565b949350505050565b5f6020828403121561492f575f5ffd5b81356001600160401b03811115614944575f5ffd5b82016101008185031215613d6b575f5ffd5b828152604060208201525f61491760408301846147c3565b5f6020828403121561497e575f5ffd5b81356001600160401b03811115614993575f5ffd5b61491784828501614490565b5f5f604083850312156149b0575f5ffd5b8235915060208301356149c28161438b565b809150509250929050565b5f5f83601f8401126149dd575f5ffd5b5081356001600160401b038111156149f3575f5ffd5b602083019150836020828501011115613f1e575f5ffd5b5f5f5f5f5f60608688031215614a1e575f5ffd5b8535945060208601356001600160401b03811115614a3a575f5ffd5b614a46888289016149cd565b90955093505060408601356001600160401b03811115614a64575f5ffd5b614a70888289016149cd565b969995985093965092949392505050565b5f5f60408385031215614a92575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016135c7565b821515815260408101613d6b6020830184614684565b5f610180828403128015614aea575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614b4c60e08401826145ff565b50610100830151614b6461010084018261ffff169052565b50610120830151614b7c61012084018261ffff169052565b50610140830151614b9661014084018263ffffffff169052565b50610160830151614bb061016084018263ffffffff169052565b5092915050565b5f5f60408385031215614bc8575f5ffd5b82359150602083013560ff811681146149c2575f5ffd5b6007811061469457614694614670565b602081016135c78284614bdf565b5f5f60608385031215614c0e575f5ffd5b614c1783614620565b915083606084011115614c28575f5ffd5b50926020919091019150565b600181811c90821680614c4857607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614c76575f5ffd5b613d6b82614620565b634e487b7160e01b5f52603260045260245ffd5b602081016135c782846146a6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156135c7576135c7614ca1565b808201808211156135c7576135c7614ca1565b5f60018201614cec57614cec614ca1565b5060010190565b5f5f8335601e19843603018112614d08575f5ffd5b8301803591506001600160401b03821115614d21575f5ffd5b602001915036819003821315613f1e575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614d52575f5ffd5b8135613d6b81614d35565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614da460a08301888a614d5d565b8281036060840152614db7818789614d5d565b90508281036080840152614dcc818587614d5d565b9b9a5050505050505050505050565b5f60208284031215614deb575f5ffd5b5051919050565b601f821115613d9857805f5260205f20601f840160051c81016020851015614e175750805b601f840160051c820191505b81811015614e36575f8155600101614e23565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115614e6a57614e6a6143bf565b614e7e81614e788454614c34565b84614df2565b6020601f821160018114614eab575f8315614e995750848201515b614ea38482614e3d565b855550614e36565b5f84815260208120601f198516915b82811015614eda5787850151825560209485019460019092019101614eba565b5084821015614ef757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b6002811015614f4057815163ffffffff16835260209283019290910190600101614f1b565b505050949350505050565b5f60208284031215614f5b575f5ffd5b8151613d6b81614d35565b60408101614f748285614bdf565b613d6b6020830184614bdf565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015614fee57603f19878603018452614fd98583516146b6565b94506020938401939190910190600101614fbd565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161503f6020830185614bdf565b6149176040830184614bdf565b6001600160401b03831115615063576150636143bf565b615077836150718354614c34565b83614df2565b5f601f8411600181146150a3575f85156150915750838201355b61509b8682614e3d565b845550614e36565b5f83815260208120601f198716915b828110156150d257868501358255602094850194600190920191016150b2565b50868210156150ee575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f615128604083018486614d5d565b95945050505050565b602081525f614917602083018486614d5d565b5f8151808452602084019350602083015f5b8281101561517d5781516001600160a01b0316865260209586019590910190600101615156565b5093949350505050565b848152836020820152608060408201525f6151a56080830185615144565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f6141f8606083018486614d5d565b61ffff81168114610bc8575f5ffd5b80356143aa816151dd565b5f60208284031215615207575f5ffd5b8135613d6b816151dd565b63ffffffff81168114610bc8575f5ffd5b80356143aa81615212565b5f6020828403121561523e575f5ffd5b8135613d6b81615212565b5f81356135c78161438b565b5f81356135c7816151dd565b5f81356135c781615212565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152dd6152c060e08501615249565b82546001600160a01b0319166001600160a01b0391909116178255565b61530d6152ed6101008501615255565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61533d61531d6101208501615255565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61537161534d6101408501615261565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613d986153816101608501615261565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016153f660e0840161439f565b61540360e08401826145ff565b5061541161010084016151ec565b61ffff1661010083015261542861012084016151ec565b61ffff1661012083015261543f6101408401615223565b63ffffffff166101408301526154586101608401615223565b63ffffffff8116610160840152614bb0565b80820281158282048414176135c7576135c7614ca1565b5f8261549b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156154d75781356154bc81615212565b63ffffffff16835260209283019291909101906001016154a8565b50505092915050565b604081016154ee8285614bdf565b613d6b6020830184614684565b5f6020828403121561550b575f5ffd5b81516001600160401b03811115615520575f5ffd5b8201601f81018413615530575f5ffd5b805161553e6144ad82614403565b8082825260208201915060208360051b85010192508683111561555f575f5ffd5b6020840193505b828410156141f85783516155798161438b565b825260209384019390910190615566565b838152606060208201525f6155a26060830185615144565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561517d5781518652602095860195909101906001016155cc565b6001600160a01b03841681526060602082018190525f9061560d90830185615144565b82810360408401526141f881856155ba565b604081525f6156316040830185615144565b828103602084015261512881856155ba565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c806390173a4111610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a0d4664f1161013c578063a0d4664f14610641578063a87f4ab914610654578063ac3d2f4214610669578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b806390173a41146105aa5780639117173c146105bf57806392312386146105d2578063929a8faf146105e557806399c6679d146106065780639c8570c81461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d74146105315780637edcd7ab1461054457806381476ec214610557578063858142431461056a5780638da5cb5b1461057d5780638dcdd86b146105855780638e5ce3ad14610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461451d565b61081d565b005b6102f06103003660046145cd565b610a2a565b61032d6103133660046145e8565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061460c565b60405180910390f35b61032d6103513660046145e8565b60096020525f90815260409020546001600160a01b031681565b61037e61037936600461462e565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a13660046145cd565b610b12565b6102f06103b4366004614656565b610bb7565b6103db6103c73660046145e8565b5f908152600f602052604090205460ff1690565b60405161033a9190614698565b6103fb6103f63660046145e8565b610bcb565b60405161033a9e9d9c9b9a999897969594939291906146e4565b6104286104233660046145e8565b610df5565b60405161033a91906148d4565b6104546104433660046145e8565b600c6020525f908152604090205481565b60405190815260200161033a565b6104906104703660046148e6565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046145e8565b6110f2565b6102f06104c13660046145cd565b611181565b6104d96104d436600461491f565b611214565b60405161033a929190614956565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a20565b6102f061051936600461496e565b611a33565b6102f061052c36600461499f565b611acb565b6102f061053f3660046145e8565b611b54565b610490610552366004614a0a565b611c52565b6102f0610565366004614a81565b611e78565b60015461032d906001600160a01b031681565b61032d611f6b565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b6105b2611f99565b60405161033a9190614aa1565b6102f06105cd3660046145e8565b611fdf565b6105b26105e03660046145e8565b612187565b6105f86105f33660046145e8565b6121e0565b60405161033a929190614ac2565b61032d6106143660046145e8565b5f908152601060205260409020546001600160a01b031690565b61049061063c366004614a0a565b612207565b6102f061064f366004614ad8565b61249f565b61065c6126c0565b60405161033a9190614af2565b61032d6106773660046145e8565b5f908152600a60205260409020546001600160a01b031690565b6102f061069f36600461496e565b6127d0565b6102f06106b2366004614bb7565b612867565b6102f06106c53660046145cd565b612952565b6102f06106d8366004614a81565b6129f9565b6104906106eb3660046145cd565b60076020525f908152604090205460ff1681565b61045460065481565b6102f061071636600461499f565b612adc565b6102f06107293660046145e8565b612b8f565b61075061073c3660046145e8565b5f908152600d602052604090205460ff1690565b60405161033a9190614bef565b61045461076b36600461491f565b612bcc565b6102f061077e3660046145cd565b612f71565b6102f0610791366004614bfd565b61300b565b60025461032d906001600160a01b031681565b6102f06107b73660046145cd565b6132a8565b6103db6107ca3660046145e8565b6132e2565b6102f06107dd3660046145cd565b61347c565b61032d6107f03660046145e8565b600a6020525f90815260409020546001600160a01b031681565b6102f06108183660046145cd565b613514565b5f6108266135a3565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336135cd565b6108cf88612b8f565b6108d88c61347c565b6108e18b612f71565b6108ea8a610a2a565b6108f389610b12565b6108fc876135de565b610905866127d0565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601694909455601792909255601894909455601993909355601a92909255601b91909155601c55607d60a31b601d556109b4611f6b565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6132a8565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613712565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613712565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a84919061460c565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac90839061460c565b60405180910390a150565b610bbf613712565b610bc8816135de565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614c34565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614c34565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614c34565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614202565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a614670565b6003811115610e4b57610e4b614670565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614c34565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614c34565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614c34565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613712565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613712565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac90839061460c565b5f61121d614202565b5f60128161122e6020870187614c66565b600381111561123f5761123f614670565b600381111561125057611250614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614c7f565b602002015163ffffffff1611845f0160208101906112ec9190614c66565b9061130b5760405163286c068d60e11b8152600401610a849190614c93565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506015546014545f919061137b426040890135614cb5565b6113859190614cc8565b61138f9190614cc8565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc60808801606089016145cd565b6001600160a01b0316815260208101919091526040015f205460ff166113f860808701606088016145cd565b906114175760405163295a6a6f60e11b8152600401610a84919061460c565b505f61142286612bcc565b60068054965090915085905f61143783614cdb565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506114d69190890135614cc8565b5f878152600e60209081526040909120600101919091558186526114fc90880188614c66565b8560200190600381111561151257611512614670565b9081600381111561152557611525614670565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261156d90608089019089016145cd565b6001600160a01b031660a08601526115886080880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526115d090880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261161d906101008901908901614d42565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a0860181905260045461166d916001600160a01b03909116903085613744565b5f61167e6080890160608a016145cd565b6001600160a01b031663fefd9a8b888461169b60808d018d614cf3565b6116a860a08f018f614cf3565b8f8060c001906116b89190614cf3565b6040518963ffffffff1660e01b81526004016116db989796959493929190614d85565b6020604051808303815f875af11580156116f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061171b9190614ddb565b5f818152600960205260409020549091506001600160a01b03168181611757576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b03168281611791576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156117ef576117ef614670565b02179055506040820151816002015560608201518160030190600261181592919061427f565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c0820151600782019061185a9082614e51565b5060e0820151600882019061186f9082614e51565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906118d79082614e51565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b9061193d908c9088908c90600401614f06565b6020604051808303815f875af1158015611959573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197d9190614f4b565b61199a57604051630d8dbe2560e01b815260040160405180910390fd5b6119aa60808b0160608c016145cd565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516119e4929190614956565b60405180910390a2885f51602061565d5f395f51905f525f6001604051611a0c929190614f66565b60405180910390a250505050505050915091565b611a28613712565b611a315f6137b1565b565b611a3b613712565b80515f5b81811015611a8f57600b838281518110611a5b57611a5b614c7f565b6020026020010151604051611a709190614f81565b908152604051908190036020019020805460ff19169055600101611a3f565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611abf9190614f97565b60405180910390a15050565b611ad3613712565b6001600160a01b03811615801590611b0457505f828152600a60205260409020546001600160a01b03828116911614155b8290611b26576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610a8490614ffa565b5f818152600d602052604090205460ff166001816006811115611ba257611ba2614670565b14611bc757816001826040516337e1404160e01b8152600401610a849392919061502b565b5f828152600d60205260409020805460ff19166002179055601354611bec9042614cc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061565d5f395f51905f5260016002604051611c46929190614f66565b60405180910390a25050565b5f5f611c5d87610df5565b5f888152600d602052604090205490915060ff166004816006811115611c8557611c85614670565b1488600483909192611cad576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611d10576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f898152600860205260409020600d01611d2d888a8361504c565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611d71929190615100565b6040519081900381206001600160e01b031960e084901b168252611d9b918a908a9060040161510f565b602060405180830381865afa158015611db6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dda9190614f4b565b9350878785611dfe57604051632f9f8ab960e01b8152600401610a84929190615131565b5050611e0989613821565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611e3b929190615131565b60405180910390a2885f51602061565d5f395f51905f5260046005604051611e64929190614f66565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611ea15760405162461bcd60e51b8152600401610a8490614ffa565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ed157611ed1614670565b14611ef657836002826040516337e1404160e01b8152600401610a849392919061502b565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061565d5f395f51905f5260026003604051611f5d929190614f66565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611fba60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff16600681600681111561200457612004614670565b146120415760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c6020526040902054806120935760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c602052604081208190556120ac84613c7e565b5f858152601160205260409020546002549192506001600160a01b03908116916120d99183911685613d72565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061210f908890879087908790600401615187565b5f604051808303815f87803b158015612126575f5ffd5b505af1158015612138573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612178929190918252602082015260400190565b60405180910390a25050505050565b6121a860405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121fd8482613d9d565b9250925050915091565b5f5f61221287610df5565b5f888152600d602052604090205490915060ff16600381600681111561223a5761223a614670565b1488600383909192612262576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156122c6576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156122fd5760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561232857604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161233a929190615100565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061237c9042614cc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906123c9908d9085908c908c906004016151be565b6020604051808303815f875af11580156123e5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124099190614f4b565b945088888661242d57604051632f9f8ab960e01b8152600401610a84929190615131565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051612461929190615131565b60405180910390a2895f51602061565d5f395f51905f526003600460405161248a929190614f66565b60405180910390a25050505095945050505050565b6124a7613712565b6127106124bc610120830161010084016151f7565b61ffff1611156125045760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b612710612519610140830161012084016151f7565b61ffff1611156125605760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612572610140820161012083016151f7565b61ffff16158061259b57505f61258f610100830160e084016145cd565b6001600160a01b031614155b6125f95760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61260b6101808201610160830161522e565b63ffffffff166126236101608301610140840161522e565b63ffffffff1610156126815760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b80601661268e828261526d565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906153a5565b6127356040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b6127d8613712565b80515f5b81811015612837576001600b8483815181106127fa576127fa614c7f565b602002602001015160405161280f9190614f81565b908152604051908190036020019020805491151560ff199092169190911790556001016127dc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611abf9190614f97565b5f546001600160a01b031633148061288957506003546001600160a01b031633145b6128d55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff161180156128eb5750600d60ff821611155b6129305760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b61294e828260ff16600d81111561294957612949614670565b613f25565b5050565b61295a613712565b6001600160a01b0381166129b05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a4a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612a94575f5ffd5b505af1158015612aa6573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c4691815260200190565b612ae4613712565b6001600160a01b03811615801590612b1557505f828152600960205260409020546001600160a01b03828116911614155b8290612b37576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611abf565b612b97613712565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612bde6020860186614c66565b6003811115612bef57612bef614670565b6003811115612c0057612c00614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c27579050505050505090505f81600160028110612c7e57612c7e614c7f565b602002015163ffffffff1611835f016020810190612c9c9190614c66565b90612cbb5760405163286c068d60e11b8152600401610a849190614c93565b5060208181015182516040805161018081018252601654815260175481860152601854818301526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b909104811661016083015260155460145460135496831697929095169592945f94919390929091612d84918c0135908c0135614cb5565b612d8e9190614cc8565b612d989190614cc8565b612da29190614cc8565b90505f612db0600186614cb5565b612dbb90600261546a565b612dc690600261546a565b612dd1906006614cc8565b90505f85845f0151612de3919061546a565b905081868560200151612df6919061546a565b612e00919061546a565b612e0a9082614cc8565b90506001861115612e52576002612e22600188614cb5565b612e2c908861546a565b8560400151612e3b919061546a565b612e459190615481565b612e4f9082614cc8565b90505b81868560c00151612e63919061546a565b612e6d919061546a565b612e779082614cc8565b905082868560600151612e8a919061546a565b612e94919061546a565b612e9e9082614cc8565b9050848460800151612eb0919061546a565b612eba9082614cc8565b90506001851115612f02576002612ed2600187614cb5565b612edc908761546a565b8560400151612eeb919061546a565b612ef59190615481565b612eff9082614cc8565b90505b60a0840151612f119082614cc8565b61010085015190915061271090612f2c9061ffff1682614cc8565b612f36908361546a565b612f409190615481565b97508780612f6457604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b612f79613712565b6001600160a01b03811615801590612f9f57506001546001600160a01b03828116911614155b8190612fbf576040516320252f0b60e01b8152600401610a84919061460c565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac90839061460c565b613013613712565b613020602082018261522e565b63ffffffff16613036604083016020840161522e565b63ffffffff161015801561305b57505f613053602083018361522e565b63ffffffff16115b61309b5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156131a45761014081015163ffffffff16613155604084016020850161522e565b63ffffffff1610156131a45760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff16156132185761016081015163ffffffff166131ce602084018461522e565b63ffffffff1610156132185760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f85600381111561322e5761322e614670565b600381111561323f5761323f614670565b815260208101919091526040015f206132599160026142bd565b5082600381111561326c5761326c614670565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161329b91906154a0565b60405180910390a2505050565b6132b0613712565b6001600160a01b0381166132d9575f604051631e4fbdf760e01b8152600401610a84919061460c565b610bc8816137b1565b5f818152600d602052604081205460ff168181600681111561330657613306614670565b0361332b57826001826040516337e1404160e01b8152600401610a849392919061502b565b600581600681111561333f5761333f614670565b036133605760405163462c7bed60e01b815260048101849052602401610a84565b600681600681111561337457613374614670565b0361339557604051633de16e3560e11b815260048101849052602401610a84565b5f6133a08483613d9d565b93509050806133c557604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561340e5761340e614670565b0217905550835f51602061565d5f395f51905f52836006604051613433929190614f66565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161346d9291906154e0565b60405180910390a25050919050565b613484613712565b6001600160a01b038116158015906134a957505f546001600160a01b03828116911614155b81906134c9576040516375ac4eb760e11b8152600401610a84919061460c565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac90839061460c565b6001600160a01b0381165f90815260076020526040902054819060ff16156135505760405163b29d459560e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac90839061460c565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6135d5614080565b610bc8816140a5565b80356136215760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f81602001351161366d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116136bc5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b3361371b611f6b565b6001600160a01b031614611a31573360405163118cdaa760e01b8152600401610a84919061460c565b6040516001600160a01b0384811660248301528381166044830152606482018390526137ab9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506140ad565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613866573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261388d91908101906154fb565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361392b576002546040516341489f1560e01b81526001600160a01b03909116906341489f15906138f79088908890869060040161558a565b5f604051808303815f87803b15801561390e575f5ffd5b505af1158015613920573d5f5f3e3d5ffd5b505050505050505050565b825f036139cc575f858152601060205260409020546001600160a01b03168015613963576139636001600160a01b0383168285613d72565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906139979089908990879060040161558a565b5f604051808303815f87803b1580156139ae575f5ffd5b505af11580156139c0573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156139e5576139e56143bf565b604051908082528060200260200182016040528015613a0e578160200160208202803683370190505b50601d549091505f9061ffff600160b01b820416906001600160a01b03168115801590613a4357506001600160a01b03811615155b15613a7f57612710613a5961ffff84168861546a565b613a639190615481565b92508215613a7f57613a7f6001600160a01b0386168285613d72565b5f613a8a8488614cb5565b90505f613a978983615481565b90505f805b8a811015613ad65782888281518110613ab757613ab7614c7f565b6020908102919091010152613acc8383614cc8565b9150600101613a9c565b505f613ae28285614cb5565b90508015613b1f578088613af760018e614cb5565b81518110613b0757613b07614c7f565b60200260200101818151613b1b9190614cc8565b9052505b600154613b39906001600160a01b038b8116911686614110565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e8b6040518463ffffffff1660e01b8152600401613b7d939291906155ea565b5f604051808303815f87803b158015613b94575f5ffd5b505af1158015613ba6573d5f5f3e3d5ffd5b5050600154613bc492506001600160a01b038c81169250165f614110565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8a604051613bf692919061561f565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613c429392919061558a565b5f604051808303815f87803b158015613c59575f5ffd5b505af1158015613c6b573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613ca657613ca6614670565b1480613cc35750600281600d811115613cc157613cc1614670565b145b15613cfb575f5b604051908082528060200260200182016040528015613cf3578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613d6157506040513d5f823e601f3d908101601f19168201604052613d5e91908101906154fb565b60015b613d6b575f613cca565b9392505050565b613d9883846001600160a01b031663a9059cbb8585604051602401613779929190615643565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613e17573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e3b9190614ddb565b90506001856006811115613e5157613e51614670565b148015613e5d57508042115b15613e7057600180935093505050613f1e565b6002856006811115613e8457613e84614670565b148015613e915750815142115b15613ea55760016003935093505050613f1e565b6003856006811115613eb957613eb9614670565b148015613ec95750816020015142115b15613edd5760016006935093505050613f1e565b6004856006811115613ef157613ef1614670565b148015613f015750816040015142115b15613f15576001600a935093505050613f1e565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff1690816006811115613f4957613f49614670565b03613f6e57826001826040516337e1404160e01b8152600401610a849392919061502b565b6005816006811115613f8257613f82614670565b03613fa35760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613fb757613fb7614670565b03613fd857604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561402157614021614670565b0217905550825f51602061565d5f395f51905f52826006604051614046929190614f66565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161329b9291906154e0565b6140886141a0565b611a3157604051631afcd79f60e31b815260040160405180910390fd5b6132b0614080565b5f5f60205f8451602086015f885af1806140cc576040513d5f823e3d81fd5b50505f513d915081156140e35780600114156140f0565b6001600160a01b0384163b155b156137ab5783604051635274afe760e01b8152600401610a84919061460c565b5f836001600160a01b031663095ea7b38484604051602401614133929190615643565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061416c84826141b9565b6137ab5761419684856001600160a01b031663095ea7b3865f604051602401613779929190615643565b6137ab84826140ad565b5f6141a96135a3565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156141f8575081156141ea57806001146141f8565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161422a614359565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156142ad579160200282015b828111156142ad578251825591602001919060010190614292565b506142b9929150614377565b5090565b6001830191839082156142ad579160200282015f5b8382111561431c57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026142d2565b801561434c5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261431c565b50506142b9929150614377565b60405180604001604052806002906020820280368337509192915050565b5b808211156142b9575f8155600101614378565b6001600160a01b0381168114610bc8575f5ffd5b80356143aa8161438b565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156143fb576143fb6143bf565b604052919050565b5f6001600160401b0382111561441b5761441b6143bf565b5060051b60200190565b5f82601f830112614434575f5ffd5b81356001600160401b0381111561444d5761444d6143bf565b614460601f8201601f19166020016143d3565b818152846020838601011115614474575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f83011261449f575f5ffd5b81356144b26144ad82614403565b6143d3565b8082825260208201915060208360051b8601019250858311156144d3575f5ffd5b602085015b838110156145135780356001600160401b038111156144f5575f5ffd5b614504886020838a0101614425565b845250602092830192016144d8565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614535575f5ffd5b88356145408161438b565b975060208901356145508161438b565b965060408901356145608161438b565b955060608901356145708161438b565b945060808901356145808161438b565b935060a089013592506145968a60c08b016143af565b91506101208901356001600160401b038111156145b1575f5ffd5b6145bd8b828c01614490565b9150509295985092959890939650565b5f602082840312156145dd575f5ffd5b8135613d6b8161438b565b5f602082840312156145f8575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106143aa575f5ffd5b5f5f6040838503121561463f575f5ffd5b61464883614620565b946020939093013593505050565b5f60608284031215614666575f5ffd5b613d6b83836143af565b634e487b7160e01b5f52602160045260245ffd5b600e811061469457614694614670565b9052565b602081016135c78284614684565b6004811061469457614694614670565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526146f4602082018f6146a6565b8c60408201528b606082015261470d608082018c6145ff565b6101c060a08201525f6147246101c083018c6146b6565b82810360c0840152614736818c6146b6565b905061474560e084018b6145ff565b61475361010084018a6145ff565b876101208401528661014084015282810361016084015261477481876146b6565b9150506147856101808301856145ff565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156137ab5781518452602093840193909101906001016147a4565b805182525f60208201516147da60208501826146a6565b506040820151604084015260608201516147f760608501826147a1565b50608082015160a084015260a082015161481460c08501826145ff565b5060c082015161020060e08501526148306102008501826146b6565b905060e083015184820361010086015261484a82826146b6565b9150506101008301516148616101208601826145ff565b506101208301516148766101408601826145ff565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148a882826146b6565b9150506101a08301516148bf6101c08601826145ff565b506101c08301518015156101e0860152613cf3565b602081525f613d6b60208301846147c3565b5f602082840312156148f6575f5ffd5b81356001600160401b0381111561490b575f5ffd5b61491784828501614425565b949350505050565b5f6020828403121561492f575f5ffd5b81356001600160401b03811115614944575f5ffd5b82016101008185031215613d6b575f5ffd5b828152604060208201525f61491760408301846147c3565b5f6020828403121561497e575f5ffd5b81356001600160401b03811115614993575f5ffd5b61491784828501614490565b5f5f604083850312156149b0575f5ffd5b8235915060208301356149c28161438b565b809150509250929050565b5f5f83601f8401126149dd575f5ffd5b5081356001600160401b038111156149f3575f5ffd5b602083019150836020828501011115613f1e575f5ffd5b5f5f5f5f5f60608688031215614a1e575f5ffd5b8535945060208601356001600160401b03811115614a3a575f5ffd5b614a46888289016149cd565b90955093505060408601356001600160401b03811115614a64575f5ffd5b614a70888289016149cd565b969995985093965092949392505050565b5f5f60408385031215614a92575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016135c7565b821515815260408101613d6b6020830184614684565b5f610180828403128015614aea575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614b4c60e08401826145ff565b50610100830151614b6461010084018261ffff169052565b50610120830151614b7c61012084018261ffff169052565b50610140830151614b9661014084018263ffffffff169052565b50610160830151614bb061016084018263ffffffff169052565b5092915050565b5f5f60408385031215614bc8575f5ffd5b82359150602083013560ff811681146149c2575f5ffd5b6007811061469457614694614670565b602081016135c78284614bdf565b5f5f60608385031215614c0e575f5ffd5b614c1783614620565b915083606084011115614c28575f5ffd5b50926020919091019150565b600181811c90821680614c4857607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614c76575f5ffd5b613d6b82614620565b634e487b7160e01b5f52603260045260245ffd5b602081016135c782846146a6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156135c7576135c7614ca1565b808201808211156135c7576135c7614ca1565b5f60018201614cec57614cec614ca1565b5060010190565b5f5f8335601e19843603018112614d08575f5ffd5b8301803591506001600160401b03821115614d21575f5ffd5b602001915036819003821315613f1e575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614d52575f5ffd5b8135613d6b81614d35565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614da460a08301888a614d5d565b8281036060840152614db7818789614d5d565b90508281036080840152614dcc818587614d5d565b9b9a5050505050505050505050565b5f60208284031215614deb575f5ffd5b5051919050565b601f821115613d9857805f5260205f20601f840160051c81016020851015614e175750805b601f840160051c820191505b81811015614e36575f8155600101614e23565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115614e6a57614e6a6143bf565b614e7e81614e788454614c34565b84614df2565b6020601f821160018114614eab575f8315614e995750848201515b614ea38482614e3d565b855550614e36565b5f84815260208120601f198516915b82811015614eda5787850151825560209485019460019092019101614eba565b5084821015614ef757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b6002811015614f4057815163ffffffff16835260209283019290910190600101614f1b565b505050949350505050565b5f60208284031215614f5b575f5ffd5b8151613d6b81614d35565b60408101614f748285614bdf565b613d6b6020830184614bdf565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015614fee57603f19878603018452614fd98583516146b6565b94506020938401939190910190600101614fbd565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161503f6020830185614bdf565b6149176040830184614bdf565b6001600160401b03831115615063576150636143bf565b615077836150718354614c34565b83614df2565b5f601f8411600181146150a3575f85156150915750838201355b61509b8682614e3d565b845550614e36565b5f83815260208120601f198716915b828110156150d257868501358255602094850194600190920191016150b2565b50868210156150ee575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f615128604083018486614d5d565b95945050505050565b602081525f614917602083018486614d5d565b5f8151808452602084019350602083015f5b8281101561517d5781516001600160a01b0316865260209586019590910190600101615156565b5093949350505050565b848152836020820152608060408201525f6151a56080830185615144565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f6141f8606083018486614d5d565b61ffff81168114610bc8575f5ffd5b80356143aa816151dd565b5f60208284031215615207575f5ffd5b8135613d6b816151dd565b63ffffffff81168114610bc8575f5ffd5b80356143aa81615212565b5f6020828403121561523e575f5ffd5b8135613d6b81615212565b5f81356135c78161438b565b5f81356135c7816151dd565b5f81356135c781615212565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152dd6152c060e08501615249565b82546001600160a01b0319166001600160a01b0391909116178255565b61530d6152ed6101008501615255565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61533d61531d6101208501615255565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61537161534d6101408501615261565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613d986153816101608501615261565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016153f660e0840161439f565b61540360e08401826145ff565b5061541161010084016151ec565b61ffff1661010083015261542861012084016151ec565b61ffff1661012083015261543f6101408401615223565b63ffffffff166101408301526154586101608401615223565b63ffffffff8116610160840152614bb0565b80820281158282048414176135c7576135c7614ca1565b5f8261549b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156154d75781356154bc81615212565b63ffffffff16835260209283019291909101906001016154a8565b50505092915050565b604081016154ee8285614bdf565b613d6b6020830184614684565b5f6020828403121561550b575f5ffd5b81516001600160401b03811115615520575f5ffd5b8201601f81018413615530575f5ffd5b805161553e6144ad82614403565b8082825260208201915060208360051b85010192508683111561555f575f5ffd5b6020840193505b828410156141f85783516155798161438b565b825260209384019390910190615566565b838152606060208201525f6155a26060830185615144565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561517d5781518652602095860195909101906001016155cc565b6001600160a01b03841681526060602082018190525f9061560d90830185615144565b82810360408401526141f881856155ba565b604081525f6156316040830185615144565b828103602084015261512881856155ba565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 3e1d5d0334..02e4b61f84 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index 88373513c9..c92ca2e41b 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -782,5 +782,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index db97caca61..3334910d5d 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -444,7 +444,12 @@ "components": [ { "internalType": "uint256", - "name": "keyGenPerNode", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", "type": "uint256" }, { @@ -467,6 +472,11 @@ "name": "publicationBase", "type": "uint256" }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, { "internalType": "address", "name": "protocolTreasury", @@ -941,6 +951,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "encryptionSchemeId", + "type": "bytes32" + } + ], + "name": "getPkVerifier", + "outputs": [ + { + "internalType": "contract IPkVerifier", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getPricingConfig", @@ -949,7 +978,12 @@ "components": [ { "internalType": "uint256", - "name": "keyGenPerNode", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", "type": "uint256" }, { @@ -972,6 +1006,11 @@ "name": "publicationBase", "type": "uint256" }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, { "internalType": "address", "name": "protocolTreasury", @@ -1006,25 +1045,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "encryptionSchemeId", - "type": "bytes32" - } - ], - "name": "getPkVerifier", - "outputs": [ - { - "internalType": "contract IPkVerifier", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -1489,7 +1509,12 @@ "components": [ { "internalType": "uint256", - "name": "keyGenPerNode", + "name": "keyGenFixedPerNode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keyGenPerEncryptionProof", "type": "uint256" }, { @@ -1512,6 +1537,11 @@ "name": "publicationBase", "type": "uint256" }, + { + "internalType": "uint256", + "name": "verificationPerProof", + "type": "uint256" + }, { "internalType": "address", "name": "protocolTreasury", @@ -1585,5 +1615,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 6d56ef23d5..b54e18c412 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index 522d8e156c..d71aeb8117 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1298,5 +1298,5 @@ }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-9ac09828abf2959f97031765d7270708a52260d9" + "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index 2d3d42e9f3..592a0ccff1 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -289,11 +289,13 @@ contract Enclave is IEnclave, OwnableUpgradeable { // Set default pricing parameters _pricingConfig = PricingConfig({ - keyGenPerNode: 100000, // 0.10 USDC + keyGenFixedPerNode: 50000, // 0.05 USDC + keyGenPerEncryptionProof: 25000, // 0.025 USDC coordinationPerPair: 5000, // 0.005 USDC availabilityPerNodePerSec: 20, // 0.00002 USDC decryptionPerNode: 150000, // 0.15 USDC publicationBase: 500000, // 0.50 USDC + verificationPerProof: 2000, // 0.002 USDC protocolTreasury: address(0), marginBps: 1000, // 10% protocolShareBps: 0, @@ -1062,7 +1064,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { require(config.marginBps <= BPS_BASE, "Margin exceeds 100%"); require(config.protocolShareBps <= BPS_BASE, "Share exceeds 100%"); require( - config.protocolShareBps == 0 || config.protocolTreasury != address(0), + config.protocolShareBps == 0 || + config.protocolTreasury != address(0), "Treasury required when protocol share > 0" ); require( @@ -1108,20 +1111,32 @@ contract Enclave is IEnclave, OwnableUpgradeable { _timeoutConfig.computeWindow + _timeoutConfig.decryptionWindow; - // Key generation cost (linear in n) - uint256 baseFee = pc.keyGenPerNode * n; + // ZK proof count per node: 6 fixed + 2 × (N-1) × L_dkg scaling + // TODO: get dkgModuliCount from E3 params instead of hardcoding + uint256 proofsPerNode = 6 + 2 * (n - 1) * 2; + + // Key generation cost: fixed per-node + per-proof (quadratic in n) + uint256 baseFee = pc.keyGenFixedPerNode * n; + baseFee += pc.keyGenPerEncryptionProof * n * proofsPerNode; + // Key generation coordination cost (quadratic in n) if (n > 1) { baseFee += (pc.coordinationPerPair * (n * (n - 1))) / 2; } - // Availability cost (linear in n * duration) + + // Proof verification cost: each node verifies all others' proofs (quadratic) + baseFee += pc.verificationPerProof * n * proofsPerNode; + + // Availability cost (linear in n × duration) baseFee += pc.availabilityPerNodePerSec * n * duration; + // Decryption cost (linear in m) baseFee += pc.decryptionPerNode * m; // Decryption coordination cost (quadratic in m) if (m > 1) { baseFee += (pc.coordinationPerPair * (m * (m - 1))) / 2; } + // Publication base cost baseFee += pc.publicationBase; diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index 585e4391a2..6b06a29ac1 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -79,11 +79,13 @@ interface IEnclave { /// @notice All pricing-related configuration for parametric E3 fee calculation struct PricingConfig { - uint256 keyGenPerNode; + uint256 keyGenFixedPerNode; + uint256 keyGenPerEncryptionProof; uint256 coordinationPerPair; uint256 availabilityPerNodePerSec; uint256 decryptionPerNode; uint256 publicationBase; + uint256 verificationPerProof; address protocolTreasury; uint16 marginBps; uint16 protocolShareBps; diff --git a/packages/enclave-contracts/scripts/deployAndSave/mockPkVerifier.ts b/packages/enclave-contracts/scripts/deployAndSave/mockPkVerifier.ts index 4be69a4b63..dc1a910fa7 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/mockPkVerifier.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/mockPkVerifier.ts @@ -18,8 +18,7 @@ export const deployAndSaveMockPkVerifier = async ( }> => { const { ethers } = await hre.network.connect(); const [signer] = await ethers.getSigners(); - const chain = - (await signer.provider?.getNetwork())?.name ?? "localhost"; + const chain = (await signer.provider?.getNetwork())?.name ?? "localhost"; const pkVerifierFactory = await ethers.getContractFactory("MockPkVerifier"); const pkVerifier = await pkVerifierFactory.deploy(); diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index a2c6292aff..fa193e2f35 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -236,11 +236,13 @@ export const deployEnclave = async ( // Set pricing config with protocol treasury console.log("Setting pricing config..."); await enclave.setPricingConfig({ - keyGenPerNode: 100000, // 0.10 USDC + keyGenFixedPerNode: 50000, // 0.05 USDC + keyGenPerEncryptionProof: 25000, // 0.025 USDC coordinationPerPair: 5000, // 0.005 USDC availabilityPerNodePerSec: 20, // 0.00002 USDC decryptionPerNode: 150000, // 0.15 USDC publicationBase: 500000, // 0.50 USDC + verificationPerProof: 2000, // 0.002 USDC protocolTreasury: ownerAddress, marginBps: 1000, // 10% protocolShareBps: 2000, // 20% diff --git a/packages/enclave-contracts/scripts/deployMocks.ts b/packages/enclave-contracts/scripts/deployMocks.ts index 1d03bc5ff5..6257ad6b0c 100644 --- a/packages/enclave-contracts/scripts/deployMocks.ts +++ b/packages/enclave-contracts/scripts/deployMocks.ts @@ -31,8 +31,7 @@ export const deployMocks = async (): Promise => { const computeProviderAddress = await computeProvider.getAddress(); console.log("Deploying Mock Decryption Verifier"); - const { decryptionVerifier } = - await deployAndSaveMockDecryptionVerifier(hre); + const { decryptionVerifier } = await deployAndSaveMockDecryptionVerifier(hre); const decryptionVerifierAddress = await decryptionVerifier.getAddress(); console.log("Deploying Mock Pk Verifier"); const { pkVerifier } = await deployAndSaveMockPkVerifier(hre); diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index 22cbbf4fb9..ebb99e0df5 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -16,6 +16,7 @@ import EnclaveTokenModule from "../../ignition/modules/enclaveToken"; import mockComputeProviderModule from "../../ignition/modules/mockComputeProvider"; import MockDecryptionVerifierModule from "../../ignition/modules/mockDecryptionVerifier"; import MockE3ProgramModule from "../../ignition/modules/mockE3Program"; +import MockPkVerifierModule from "../../ignition/modules/mockPkVerifier"; import MockStableTokenModule from "../../ignition/modules/mockStableToken"; import SlashingManagerModule from "../../ignition/modules/slashingManager"; import { @@ -26,6 +27,7 @@ import { } from "../../types"; import type { Enclave } from "../../types/contracts/Enclave"; import type { MockUSDC } from "../../types/contracts/test/MockStableToken.sol/MockUSDC"; +import { encodePkProof } from "../fixtures"; const { ethers, ignition, networkHelpers } = await network.connect(); const { loadFixture, time, mine } = networkHelpers; @@ -44,11 +46,13 @@ describe("E3 Pricing", function () { // Default pricing config matching initialize() defaults const defaultPricingConfig = { - keyGenPerNode: 100000n, + keyGenFixedPerNode: 50000n, + keyGenPerEncryptionProof: 25000n, coordinationPerPair: 5000n, availabilityPerNodePerSec: 20n, decryptionPerNode: 150000n, publicationBase: 500000n, + verificationPerProof: 2000n, protocolTreasury: ethers.ZeroAddress, marginBps: 1000, protocolShareBps: 0, @@ -58,11 +62,13 @@ describe("E3 Pricing", function () { // Convert ethers Result to a plain object that can be spread const toPlainConfig = (pc: any) => ({ - keyGenPerNode: pc.keyGenPerNode, + keyGenFixedPerNode: pc.keyGenFixedPerNode, + keyGenPerEncryptionProof: pc.keyGenPerEncryptionProof, coordinationPerPair: pc.coordinationPerPair, availabilityPerNodePerSec: pc.availabilityPerNodePerSec, decryptionPerNode: pc.decryptionPerNode, publicationBase: pc.publicationBase, + verificationPerProof: pc.verificationPerProof, protocolTreasury: pc.protocolTreasury, marginBps: pc.marginBps, protocolShareBps: pc.protocolShareBps, @@ -131,8 +137,8 @@ describe("E3 Pricing", function () { } await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(e3Id); - const publicKeyHash = ethers.id(publicKey); - await registry.publishCommittee(e3Id, nodes, publicKey, publicKeyHash); + const proof = encodePkProof(ethers.keccak256(publicKey)); + await registry.publishCommittee(e3Id, nodes, publicKey, proof); }; const setup = async () => { @@ -259,6 +265,8 @@ describe("E3 Pricing", function () { await ignition.deploy(MockDecryptionVerifierModule); const { mockE3Program: e3Program } = await ignition.deploy(MockE3ProgramModule); + const { mockPkVerifier: pkVerifier } = + await ignition.deploy(MockPkVerifierModule); await enclave.enableE3Program(await e3Program.getAddress()); await enclave.setE3ProgramsParams([encodedE3ProgramParams]); @@ -266,6 +274,10 @@ describe("E3 Pricing", function () { encryptionSchemeId, await decryptionVerifier.getAddress(), ); + await enclave.setPkVerifier( + encryptionSchemeId, + await pkVerifier.getAddress(), + ); // Operators await licenseToken.setTransferRestriction(false); @@ -305,6 +317,7 @@ describe("E3 Pricing", function () { ["address"], ["0x1234567890123456789012345678901234567890"], ), + proofAggregationEnabled: false, }; return { @@ -323,7 +336,7 @@ describe("E3 Pricing", function () { slashingManager, e3RefundManager, request, - mocks: { decryptionVerifier, e3Program, mockComputeProvider }, + mocks: { decryptionVerifier, e3Program, mockComputeProvider, pkVerifier }, }; }; @@ -372,9 +385,12 @@ describe("E3 Pricing", function () { // Get pricing config const pc = await enclave.getPricingConfig(); - // Calculate expected fee - let baseFee = pc.keyGenPerNode * n; + // Calculate expected fee (proof-aware) + const proofsPerNode = 6n + 2n * (n - 1n) * 2n; + let baseFee = pc.keyGenFixedPerNode * n; + baseFee += pc.keyGenPerEncryptionProof * n * proofsPerNode; if (n > 1n) baseFee += (pc.coordinationPerPair * n * (n - 1n)) / 2n; + baseFee += pc.verificationPerProof * n * proofsPerNode; baseFee += pc.availabilityPerNodePerSec * n * duration; baseFee += pc.decryptionPerNode * m; if (m > 1n) baseFee += (pc.coordinationPerPair * m * (m - 1n)) / 2n; @@ -456,7 +472,8 @@ describe("E3 Pricing", function () { const { enclave } = await loadFixture(setup); const newConfig = { ...defaultPricingConfig, - keyGenPerNode: 200000n, + keyGenFixedPerNode: 100000n, + keyGenPerEncryptionProof: 50000n, coordinationPerPair: 10000n, availabilityPerNodePerSec: 40n, decryptionPerNode: 300000n, @@ -469,7 +486,8 @@ describe("E3 Pricing", function () { ); const stored = await enclave.getPricingConfig(); - expect(stored.keyGenPerNode).to.equal(200000n); + expect(stored.keyGenFixedPerNode).to.equal(100000n); + expect(stored.keyGenPerEncryptionProof).to.equal(50000n); expect(stored.coordinationPerPair).to.equal(10000n); expect(stored.availabilityPerNodePerSec).to.equal(40n); expect(stored.decryptionPerNode).to.equal(300000n); @@ -484,7 +502,8 @@ describe("E3 Pricing", function () { // Double base costs await enclave.setPricingConfig({ ...defaultPricingConfig, - keyGenPerNode: 200000n, + keyGenFixedPerNode: 100000n, + keyGenPerEncryptionProof: 50000n, coordinationPerPair: 10000n, availabilityPerNodePerSec: 40n, decryptionPerNode: 300000n, @@ -591,6 +610,7 @@ describe("E3 Pricing", function () { ["address"], ["0x1234567890123456789012345678901234567890"], ), + proofAggregationEnabled: false, }; // Make request with large approval to avoid fee mismatch @@ -673,6 +693,7 @@ describe("E3 Pricing", function () { ["address"], ["0x1234567890123456789012345678901234567890"], ), + proofAggregationEnabled: false, }; // Make request with large approval @@ -729,11 +750,13 @@ describe("E3 Pricing", function () { it("has correct default pricing config from initialize", async function () { const { enclave } = await loadFixture(setup); const pc = await enclave.getPricingConfig(); - expect(pc.keyGenPerNode).to.equal(100000); + expect(pc.keyGenFixedPerNode).to.equal(50000); + expect(pc.keyGenPerEncryptionProof).to.equal(25000); expect(pc.coordinationPerPair).to.equal(5000); expect(pc.availabilityPerNodePerSec).to.equal(20); expect(pc.decryptionPerNode).to.equal(150000); expect(pc.publicationBase).to.equal(500000); + expect(pc.verificationPerProof).to.equal(2000); expect(pc.marginBps).to.equal(1000); expect(pc.protocolShareBps).to.equal(0); expect(pc.protocolTreasury).to.equal(ethers.ZeroAddress); From afd1fffb6504add0fc7489d169364e10fe18af7d Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Sat, 21 Mar 2026 23:37:29 +0500 Subject: [PATCH 05/11] fix: update contract addresses --- examples/CRISP/enclave.config.yaml | 32 ++++---- .../crisp-contracts/deployed_contracts.json | 78 +++++++++---------- examples/CRISP/server/.env.example | 2 +- .../enclave-contracts/contracts/Enclave.sol | 23 ++++++ 4 files changed, 79 insertions(+), 56 deletions(-) diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index 6a37ccad3a..df43114041 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -1,25 +1,25 @@ chains: - - name: "localhost" - rpc_url: "ws://localhost:8545" + - name: localhost + rpc_url: ws://localhost:8545 contracts: e3_program: - address: "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00" - deploy_block: 31 + address: "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570" + deploy_block: 33 enclave: address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - deploy_block: 13 + deploy_block: 15 ciphernode_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 9 + deploy_block: 11 bonding_registry: address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - deploy_block: 10 + deploy_block: 12 slashing_manager: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - deploy_block: 8 + deploy_block: 10 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - deploy_block: 4 + deploy_block: 6 program: dev: true # risc0: @@ -32,35 +32,35 @@ program: # onchain: true # true = onchain requests, false = offchain nodes: cn1: - address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' quic_port: 9201 autonetkey: true autopassword: true cn2: - address: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" + address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC' quic_port: 9202 autonetkey: true autopassword: true cn3: - address: "0x90F79bf6EB2c4f870365E785982E1f101E93b906" + address: '0x90F79bf6EB2c4f870365E785982E1f101E93b906' quic_port: 9203 autonetkey: true autopassword: true cn4: - address: "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" + address: '0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65' quic_port: 9204 autonetkey: true autopassword: true cn5: - address: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" + address: '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc' quic_port: 9205 autonetkey: true autopassword: true ag: - address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' quic_port: 9206 autonetkey: true autopassword: true role: - type: "aggregator" + type: aggregator diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index f20d36aecf..998491cfd6 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -151,21 +151,21 @@ }, "localhost": { "PoseidonT3": { - "blockNumber": 3, + "blockNumber": 5, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 4, + "blockNumber": 6, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 5, + "blockNumber": 7, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { @@ -174,14 +174,14 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 7, + "blockNumber": 9, "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 8, + "blockNumber": 10, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "CiphernodeRegistryOwnable": { @@ -196,7 +196,7 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 9, + "blockNumber": 11, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "BondingRegistry": { @@ -218,7 +218,7 @@ "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 10, + "blockNumber": 12, "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { @@ -241,7 +241,7 @@ "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 13, + "blockNumber": 15, "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "E3RefundManager": { @@ -257,70 +257,70 @@ "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, - "blockNumber": 15, + "blockNumber": 17, "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, "MockComputeProvider": { - "blockNumber": 17, - "address": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E" + "blockNumber": 19, + "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" }, "MockDecryptionVerifier": { - "blockNumber": 18, - "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" + "blockNumber": 20, + "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" }, "MockPkVerifier": { - "blockNumber": 19, - "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" + "blockNumber": 21, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" }, "MockE3Program": { - "blockNumber": 20, - "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + "blockNumber": 22, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" }, "ZKTranscriptLib": { - "blockNumber": 22, - "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" + "blockNumber": 24, + "address": "0x851356ae760d987E095750cCeb3bC6014560891C" }, "RecursiveAggregationFoldVerifier": { - "blockNumber": 23, - "address": "0x851356ae760d987E095750cCeb3bC6014560891C" + "blockNumber": 25, + "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" }, "ThresholdDecryptedSharesAggregationVerifier": { - "blockNumber": 24, - "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" + "blockNumber": 26, + "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" }, "ThresholdPkAggregationVerifier": { - "blockNumber": 25, - "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" + "blockNumber": 27, + "address": "0x998abeb3E57409262aE5b751f60747921B33613E" }, "BfvDecryptionVerifier": { - "blockNumber": 26, - "address": "0x998abeb3E57409262aE5b751f60747921B33613E" + "blockNumber": 28, + "address": "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49" }, "BfvPkVerifier": { - "blockNumber": 28, - "address": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528" + "blockNumber": 30, + "address": "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf" }, "MockRISC0Verifier": { - "address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF", - "blockNumber": 30 + "address": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf", + "blockNumber": 32 }, "HonkVerifier": { - "address": "0x9d4454B023096f34B160D6B654540c56A1F81688", - "blockNumber": 31 + "address": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", + "blockNumber": 33 }, "CRISPProgram": { - "address": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", - "blockNumber": 31, + "address": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", + "blockNumber": 33, "constructorArgs": { "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "verifierAddress": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF", - "honkVerifierAddress": "0x9d4454B023096f34B160D6B654540c56A1F81688", + "verifierAddress": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf", + "honkVerifierAddress": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" } }, "MockVotingToken": { - "address": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D", - "blockNumber": 33 + "address": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029", + "blockNumber": 35 } } } \ No newline at end of file diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 652915fdd5..af56812859 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -15,7 +15,7 @@ CRON_API_KEY=1234567890 # Based on Default Anvil Deployments (Only for testing) ENCLAVE_ADDRESS="0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" CIPHERNODE_REGISTRY_ADDRESS="0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" -E3_PROGRAM_ADDRESS="0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00" +E3_PROGRAM_ADDRESS="0x36C02dA8a0983159322a80FFE9F24b1acfF8B570" FEE_TOKEN_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" # E3 Config diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index 592a0ccff1..7a1faa30d8 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -205,6 +205,11 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @notice The input deadline end is before the start error InvalidInputDeadlineEnd(uint256 end); + /// @notice Below minimum committee size + error CommitteeSizeTooSmall(CommitteeSize committeeSize); + /// @notice Below minimum threshold + error ThresholdTooSmall(uint256 threshold); + /// @notice The duties are completed, and ciphernodes are not required to act anymore for this E3 /// @param e3Id The ID of the E3 /// @param expiration The expiration timestamp of the E3 @@ -1104,6 +1109,24 @@ contract Enclave is IEnclave, OwnableUpgradeable { PricingConfig memory pc = _pricingConfig; + if (pc.minCommitteeSize > 0) { + require( + threshold[1] >= pc.minCommitteeSize, + CommitteeSizeTooSmall(requestParams.committeeSize) + ); + } + if (pc.minThreshold > 0) { + require( + threshold[0] >= pc.minThreshold, + ThresholdTooSmall(threshold[0]) + ); + } + + require( + requestParams.inputWindow[1] >= requestParams.inputWindow[0], + InvalidInputDeadlineEnd(requestParams.inputWindow[1]) + ); + // Duration covers the full availability period uint256 duration = requestParams.inputWindow[1] - requestParams.inputWindow[0] + From 5f2f2a00f968a413507715a5049483efe2e9c8ce Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Sun, 22 Mar 2026 15:26:06 +0500 Subject: [PATCH 06/11] fix: review comments --- .github/workflows/ci.yml | 4 ++-- packages/enclave-contracts/contracts/Enclave.sol | 14 +++++++++++--- .../enclave-contracts/scripts/deployEnclave.ts | 5 +++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32fb8710d0..649dc587fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -537,7 +537,7 @@ jobs: needs: [detect_changes] if: needs.detect_changes.outputs.build_enclave_cli == 'true' timeout-minutes: 20 - runs-on: + runs-on: group: enclave-ci labels: [enclave-ci-runner] permissions: @@ -655,7 +655,7 @@ jobs: crisp_e2e: needs: [detect_changes, build_enclave_cli, build_crisp_sdk] - if: needs.detect_changes.outputs.crisp == 'true' + if: needs.detect_changes.outputs.crisp == 'true' timeout-minutes: 45 runs-on: group: enclave-ci diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index 7a1faa30d8..d31fcdcaae 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -107,12 +107,18 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @notice Maps committee size to threshold values [quorum, total] mapping(CommitteeSize => uint32[2] threshold) public committeeThresholds; + /// @notice Maps E3 ID to the protocol share BPS snapshotted at request time + mapping(uint256 e3Id => uint16 protocolShareBps) + internal _e3ProtocolShareBps; + + /// @notice Maps E3 ID to the protocol treasury snapshotted at request time + mapping(uint256 e3Id => address protocolTreasury) + internal _e3ProtocolTreasury; /// @notice Global timeout configuration E3TimeoutConfig internal _timeoutConfig; /// @notice All pricing-related configuration PricingConfig internal _pricingConfig; - /// @notice Basis points denominator uint16 internal constant BPS_BASE = 10000; @@ -362,6 +368,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { e3Payments[e3Id] = e3Fee; _e3FeeTokens[e3Id] = feeToken; + _e3ProtocolShareBps[e3Id] = _pricingConfig.protocolShareBps; + _e3ProtocolTreasury[e3Id] = _pricingConfig.protocolTreasury; // Initialize E3 Lifecycle _e3Stages[e3Id] = E3Stage.Requested; @@ -564,8 +572,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { // Split between protocol treasury and CN rewards uint256 protocolAmount = 0; - uint16 _protocolShareBps = _pricingConfig.protocolShareBps; - address _protocolTreasury = _pricingConfig.protocolTreasury; + uint16 _protocolShareBps = _e3ProtocolShareBps[e3Id]; + address _protocolTreasury = _e3ProtocolTreasury[e3Id]; if (_protocolShareBps > 0 && _protocolTreasury != address(0)) { protocolAmount = (totalAmount * uint256(_protocolShareBps)) / diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index fa193e2f35..1628d41899 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -234,6 +234,7 @@ export const deployEnclave = async ( const encryptionSchemeId = ethers.keccak256(ethers.toUtf8Bytes("fhe.rs:BFV")); // Set pricing config with protocol treasury + const protocolTreasury = process.env.PROTOCOL_TREASURY || ownerAddress; console.log("Setting pricing config..."); await enclave.setPricingConfig({ keyGenFixedPerNode: 50000, // 0.05 USDC @@ -243,13 +244,13 @@ export const deployEnclave = async ( decryptionPerNode: 150000, // 0.15 USDC publicationBase: 500000, // 0.50 USDC verificationPerProof: 2000, // 0.002 USDC - protocolTreasury: ownerAddress, + protocolTreasury: protocolTreasury, marginBps: 1000, // 10% protocolShareBps: 2000, // 20% minCommitteeSize: 0, minThreshold: 0, }); - console.log("Pricing config set (treasury:", ownerAddress, ")"); + console.log("Pricing config set (treasury:", protocolTreasury, ")"); if (shouldDeployMocks) { const { From 114bc3be30bf2673988260c8425a00bcc8961a3c Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Sun, 22 Mar 2026 22:39:35 +0500 Subject: [PATCH 07/11] fix: review comments --- .../enclave-contracts/contracts/Enclave.sol | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index d31fcdcaae..b1bc806e2e 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -555,21 +555,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { return; } - if (activeLength == 0) { - address requester = _e3Requesters[e3Id]; - if (requester != address(0)) { - paymentToken.safeTransfer(requester, totalAmount); - } - e3RefundManager.distributeSlashedFundsOnSuccess( - e3Id, - activeNodes, - paymentToken - ); - return; - } - - uint256[] memory amounts = new uint256[](activeLength); - // Split between protocol treasury and CN rewards uint256 protocolAmount = 0; uint16 _protocolShareBps = _e3ProtocolShareBps[e3Id]; @@ -585,6 +570,21 @@ contract Enclave is IEnclave, OwnableUpgradeable { uint256 cnAmount = totalAmount - protocolAmount; + if (activeLength == 0) { + address requester = _e3Requesters[e3Id]; + if (requester != address(0) && cnAmount > 0) { + paymentToken.safeTransfer(requester, cnAmount); + } + e3RefundManager.distributeSlashedFundsOnSuccess( + e3Id, + activeNodes, + paymentToken + ); + return; + } + + uint256[] memory amounts = new uint256[](activeLength); + // Distribute CN share equally among active (non-expelled) committee members uint256 amount = cnAmount / activeLength; uint256 distributed = 0; From 3ba20ad9bbfaaaf9e1f93d89561c7ac11845887e Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Mon, 23 Mar 2026 11:32:30 +0500 Subject: [PATCH 08/11] fix: update contracts --- templates/default/enclave.config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/default/enclave.config.yaml b/templates/default/enclave.config.yaml index 682b02a85f..143048a50a 100644 --- a/templates/default/enclave.config.yaml +++ b/templates/default/enclave.config.yaml @@ -18,7 +18,7 @@ chains: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" deploy_block: 5 e3_program: - address: "0x9d4454B023096f34B160D6B654540c56A1F81688" + address: "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00" deploy_block: 34 program: dev: true From 8089a4a96d0bc0b99c8c12519cdca87785abcc26 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Mon, 23 Mar 2026 17:43:38 +0500 Subject: [PATCH 09/11] fix: resolve conflicts --- agent/RULES.md | 37 ++++++++++--------- .../contracts/Enclave.sol/Enclave.json | 28 ++++++++++++-- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IEnclave.sol/IEnclave.json | 2 +- .../ISlashingManager.json | 2 +- .../CiphernodeRegistryOwnable.json | 2 +- .../test/BfvDecryptionVerifier.spec.ts | 10 ++--- .../test/E3Lifecycle/E3Integration.spec.ts | 11 +++++- .../test/Pricing/Pricing.spec.ts | 4 +- 10 files changed, 64 insertions(+), 36 deletions(-) diff --git a/agent/RULES.md b/agent/RULES.md index 5fce93fb00..11cf5b2466 100644 --- a/agent/RULES.md +++ b/agent/RULES.md @@ -1,7 +1,8 @@ # Enclave — Agent Rules These rules apply to any LLM agent working on this codebase. Tool-specific config files -(.cursor/rules/enclave.mdc, CLAUDE.md, etc.) should reference this file rather than duplicating its content. +(.cursor/rules/enclave.mdc, CLAUDE.md, etc.) should reference this file rather than duplicating its +content. ## Project Structure @@ -13,22 +14,22 @@ These rules apply to any LLM agent working on this codebase. Tool-specific confi ## Flow-Trace Documentation (`agent/flow-trace/`) -The `agent/flow-trace/` directory contains detailed protocol documentation that traces the -complete lifecycle of the Enclave protocol — from node registration through DKG, computation, -decryption, failure handling, and deactivation. +The `agent/flow-trace/` directory contains detailed protocol documentation that traces the complete +lifecycle of the Enclave protocol — from node registration through DKG, computation, decryption, +failure handling, and deactivation. ### When to consult Read the relevant flow-trace file **before** modifying code in any of these areas: -| Area | File to read | -|------|-------------| -| CLI commands (`setup`, `register`, `activate`, `status`), on-chain registration, IMT | `01_REGISTRATION.md` | -| ENCL bonding, USDC tickets, activation thresholds, exit queue | `02_TOKENS_AND_ACTIVATION.md` | -| E3 requests, fee payment, committee selection, sortition, ticket submission | `03_E3_REQUEST_AND_COMMITTEE.md` | -| DKG, BFV keygen, ZK proofs (C0–C7), Shamir shares, key aggregation, decryption | `04_DKG_AND_COMPUTATION.md` | -| Timeouts, `markE3Failed`, refunds, accusations, slashing (Lane A/B) | `05_FAILURE_REFUND_SLASHING.md` | -| Deactivation, deregistration, E3 completion, node shutdown, sync/restart | `06_DEACTIVATION_AND_COMPLETION.md` | +| Area | File to read | +| ------------------------------------------------------------------------------------ | ----------------------------------- | +| CLI commands (`setup`, `register`, `activate`, `status`), on-chain registration, IMT | `01_REGISTRATION.md` | +| ENCL bonding, USDC tickets, activation thresholds, exit queue | `02_TOKENS_AND_ACTIVATION.md` | +| E3 requests, fee payment, committee selection, sortition, ticket submission | `03_E3_REQUEST_AND_COMMITTEE.md` | +| DKG, BFV keygen, ZK proofs (C0–C7), Shamir shares, key aggregation, decryption | `04_DKG_AND_COMPUTATION.md` | +| Timeouts, `markE3Failed`, refunds, accusations, slashing (Lane A/B) | `05_FAILURE_REFUND_SLASHING.md` | +| Deactivation, deregistration, E3 completion, node shutdown, sync/restart | `06_DEACTIVATION_AND_COMPLETION.md` | Always start from `00_INDEX.md` if unsure which file is relevant. @@ -37,8 +38,8 @@ Always start from `00_INDEX.md` if unsure which file is relevant. 1. Open `agent/flow-trace/00_INDEX.md` — it has a topic table and end-to-end flow summaries 2. Find the file that covers your area of interest 3. Each file traces the flow call-by-call with file paths, function names, and event names -4. The index also contains a "Verified Bugs & Protocol Concerns" section — check it before - assuming current behavior is correct +4. The index also contains a "Verified Bugs & Protocol Concerns" section — check it before assuming + current behavior is correct ### When to update @@ -55,10 +56,10 @@ Update flow-trace docs **in the same PR** when any of these happen: - Edit the specific file that covers the changed area — keep changes scoped - If a change spans multiple files, update all affected files -- Update `00_INDEX.md` only when adding/removing/renaming a file, or when the end-to-end - flow summaries or the contract interaction map change -- Preserve the existing format: step-by-step traces with `File:` references pointing to - actual source paths +- Update `00_INDEX.md` only when adding/removing/renaming a file, or when the end-to-end flow + summaries or the contract interaction map change +- Preserve the existing format: step-by-step traces with `File:` references pointing to actual + source paths - Keep the "Verified Bugs" table in `00_INDEX.md` current — mark fixed bugs, add new ones - Do NOT rewrite entire files for small changes — surgical edits only diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index d1d1d87eec..7431b5ce42 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -62,6 +62,17 @@ "name": "CommitteeSizeNotConfigured", "type": "error" }, + { + "inputs": [ + { + "internalType": "enum IEnclave.CommitteeSize", + "name": "committeeSize", + "type": "uint8" + } + ], + "name": "CommitteeSizeTooSmall", + "type": "error" + }, { "inputs": [ { @@ -340,6 +351,17 @@ "name": "SafeERC20FailedOperation", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + } + ], + "name": "ThresholdTooSmall", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -2375,11 +2397,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615689806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c806390173a4111610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a0d4664f1161013c578063a0d4664f14610641578063a87f4ab914610654578063ac3d2f4214610669578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b806390173a41146105aa5780639117173c146105bf57806392312386146105d2578063929a8faf146105e557806399c6679d146106065780639c8570c81461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d74146105315780637edcd7ab1461054457806381476ec214610557578063858142431461056a5780638da5cb5b1461057d5780638dcdd86b146105855780638e5ce3ad14610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461451d565b61081d565b005b6102f06103003660046145cd565b610a2a565b61032d6103133660046145e8565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061460c565b60405180910390f35b61032d6103513660046145e8565b60096020525f90815260409020546001600160a01b031681565b61037e61037936600461462e565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a13660046145cd565b610b12565b6102f06103b4366004614656565b610bb7565b6103db6103c73660046145e8565b5f908152600f602052604090205460ff1690565b60405161033a9190614698565b6103fb6103f63660046145e8565b610bcb565b60405161033a9e9d9c9b9a999897969594939291906146e4565b6104286104233660046145e8565b610df5565b60405161033a91906148d4565b6104546104433660046145e8565b600c6020525f908152604090205481565b60405190815260200161033a565b6104906104703660046148e6565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046145e8565b6110f2565b6102f06104c13660046145cd565b611181565b6104d96104d436600461491f565b611214565b60405161033a929190614956565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a20565b6102f061051936600461496e565b611a33565b6102f061052c36600461499f565b611acb565b6102f061053f3660046145e8565b611b54565b610490610552366004614a0a565b611c52565b6102f0610565366004614a81565b611e78565b60015461032d906001600160a01b031681565b61032d611f6b565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b6105b2611f99565b60405161033a9190614aa1565b6102f06105cd3660046145e8565b611fdf565b6105b26105e03660046145e8565b612187565b6105f86105f33660046145e8565b6121e0565b60405161033a929190614ac2565b61032d6106143660046145e8565b5f908152601060205260409020546001600160a01b031690565b61049061063c366004614a0a565b612207565b6102f061064f366004614ad8565b61249f565b61065c6126c0565b60405161033a9190614af2565b61032d6106773660046145e8565b5f908152600a60205260409020546001600160a01b031690565b6102f061069f36600461496e565b6127d0565b6102f06106b2366004614bb7565b612867565b6102f06106c53660046145cd565b612952565b6102f06106d8366004614a81565b6129f9565b6104906106eb3660046145cd565b60076020525f908152604090205460ff1681565b61045460065481565b6102f061071636600461499f565b612adc565b6102f06107293660046145e8565b612b8f565b61075061073c3660046145e8565b5f908152600d602052604090205460ff1690565b60405161033a9190614bef565b61045461076b36600461491f565b612bcc565b6102f061077e3660046145cd565b612f71565b6102f0610791366004614bfd565b61300b565b60025461032d906001600160a01b031681565b6102f06107b73660046145cd565b6132a8565b6103db6107ca3660046145e8565b6132e2565b6102f06107dd3660046145cd565b61347c565b61032d6107f03660046145e8565b600a6020525f90815260409020546001600160a01b031681565b6102f06108183660046145cd565b613514565b5f6108266135a3565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336135cd565b6108cf88612b8f565b6108d88c61347c565b6108e18b612f71565b6108ea8a610a2a565b6108f389610b12565b6108fc876135de565b610905866127d0565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601694909455601792909255601894909455601993909355601a92909255601b91909155601c55607d60a31b601d556109b4611f6b565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6132a8565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613712565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613712565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a84919061460c565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac90839061460c565b60405180910390a150565b610bbf613712565b610bc8816135de565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614c34565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614c34565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614c34565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614202565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a614670565b6003811115610e4b57610e4b614670565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614c34565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614c34565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614c34565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613712565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613712565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac90839061460c565b5f61121d614202565b5f60128161122e6020870187614c66565b600381111561123f5761123f614670565b600381111561125057611250614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614c7f565b602002015163ffffffff1611845f0160208101906112ec9190614c66565b9061130b5760405163286c068d60e11b8152600401610a849190614c93565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506015546014545f919061137b426040890135614cb5565b6113859190614cc8565b61138f9190614cc8565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc60808801606089016145cd565b6001600160a01b0316815260208101919091526040015f205460ff166113f860808701606088016145cd565b906114175760405163295a6a6f60e11b8152600401610a84919061460c565b505f61142286612bcc565b60068054965090915085905f61143783614cdb565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506114d69190890135614cc8565b5f878152600e60209081526040909120600101919091558186526114fc90880188614c66565b8560200190600381111561151257611512614670565b9081600381111561152557611525614670565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261156d90608089019089016145cd565b6001600160a01b031660a08601526115886080880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526115d090880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261161d906101008901908901614d42565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a0860181905260045461166d916001600160a01b03909116903085613744565b5f61167e6080890160608a016145cd565b6001600160a01b031663fefd9a8b888461169b60808d018d614cf3565b6116a860a08f018f614cf3565b8f8060c001906116b89190614cf3565b6040518963ffffffff1660e01b81526004016116db989796959493929190614d85565b6020604051808303815f875af11580156116f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061171b9190614ddb565b5f818152600960205260409020549091506001600160a01b03168181611757576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b03168281611791576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156117ef576117ef614670565b02179055506040820151816002015560608201518160030190600261181592919061427f565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c0820151600782019061185a9082614e51565b5060e0820151600882019061186f9082614e51565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906118d79082614e51565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b9061193d908c9088908c90600401614f06565b6020604051808303815f875af1158015611959573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197d9190614f4b565b61199a57604051630d8dbe2560e01b815260040160405180910390fd5b6119aa60808b0160608c016145cd565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516119e4929190614956565b60405180910390a2885f51602061565d5f395f51905f525f6001604051611a0c929190614f66565b60405180910390a250505050505050915091565b611a28613712565b611a315f6137b1565b565b611a3b613712565b80515f5b81811015611a8f57600b838281518110611a5b57611a5b614c7f565b6020026020010151604051611a709190614f81565b908152604051908190036020019020805460ff19169055600101611a3f565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611abf9190614f97565b60405180910390a15050565b611ad3613712565b6001600160a01b03811615801590611b0457505f828152600a60205260409020546001600160a01b03828116911614155b8290611b26576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610a8490614ffa565b5f818152600d602052604090205460ff166001816006811115611ba257611ba2614670565b14611bc757816001826040516337e1404160e01b8152600401610a849392919061502b565b5f828152600d60205260409020805460ff19166002179055601354611bec9042614cc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061565d5f395f51905f5260016002604051611c46929190614f66565b60405180910390a25050565b5f5f611c5d87610df5565b5f888152600d602052604090205490915060ff166004816006811115611c8557611c85614670565b1488600483909192611cad576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611d10576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f898152600860205260409020600d01611d2d888a8361504c565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611d71929190615100565b6040519081900381206001600160e01b031960e084901b168252611d9b918a908a9060040161510f565b602060405180830381865afa158015611db6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dda9190614f4b565b9350878785611dfe57604051632f9f8ab960e01b8152600401610a84929190615131565b5050611e0989613821565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611e3b929190615131565b60405180910390a2885f51602061565d5f395f51905f5260046005604051611e64929190614f66565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611ea15760405162461bcd60e51b8152600401610a8490614ffa565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ed157611ed1614670565b14611ef657836002826040516337e1404160e01b8152600401610a849392919061502b565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061565d5f395f51905f5260026003604051611f5d929190614f66565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611fba60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff16600681600681111561200457612004614670565b146120415760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c6020526040902054806120935760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c602052604081208190556120ac84613c7e565b5f858152601160205260409020546002549192506001600160a01b03908116916120d99183911685613d72565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061210f908890879087908790600401615187565b5f604051808303815f87803b158015612126575f5ffd5b505af1158015612138573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612178929190918252602082015260400190565b60405180910390a25050505050565b6121a860405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121fd8482613d9d565b9250925050915091565b5f5f61221287610df5565b5f888152600d602052604090205490915060ff16600381600681111561223a5761223a614670565b1488600383909192612262576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156122c6576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156122fd5760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561232857604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161233a929190615100565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061237c9042614cc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906123c9908d9085908c908c906004016151be565b6020604051808303815f875af11580156123e5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124099190614f4b565b945088888661242d57604051632f9f8ab960e01b8152600401610a84929190615131565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051612461929190615131565b60405180910390a2895f51602061565d5f395f51905f526003600460405161248a929190614f66565b60405180910390a25050505095945050505050565b6124a7613712565b6127106124bc610120830161010084016151f7565b61ffff1611156125045760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b612710612519610140830161012084016151f7565b61ffff1611156125605760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612572610140820161012083016151f7565b61ffff16158061259b57505f61258f610100830160e084016145cd565b6001600160a01b031614155b6125f95760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61260b6101808201610160830161522e565b63ffffffff166126236101608301610140840161522e565b63ffffffff1610156126815760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b80601661268e828261526d565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906153a5565b6127356040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b6127d8613712565b80515f5b81811015612837576001600b8483815181106127fa576127fa614c7f565b602002602001015160405161280f9190614f81565b908152604051908190036020019020805491151560ff199092169190911790556001016127dc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611abf9190614f97565b5f546001600160a01b031633148061288957506003546001600160a01b031633145b6128d55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff161180156128eb5750600d60ff821611155b6129305760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b61294e828260ff16600d81111561294957612949614670565b613f25565b5050565b61295a613712565b6001600160a01b0381166129b05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a4a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612a94575f5ffd5b505af1158015612aa6573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c4691815260200190565b612ae4613712565b6001600160a01b03811615801590612b1557505f828152600960205260409020546001600160a01b03828116911614155b8290612b37576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611abf565b612b97613712565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612bde6020860186614c66565b6003811115612bef57612bef614670565b6003811115612c0057612c00614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c27579050505050505090505f81600160028110612c7e57612c7e614c7f565b602002015163ffffffff1611835f016020810190612c9c9190614c66565b90612cbb5760405163286c068d60e11b8152600401610a849190614c93565b5060208181015182516040805161018081018252601654815260175481860152601854818301526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b909104811661016083015260155460145460135496831697929095169592945f94919390929091612d84918c0135908c0135614cb5565b612d8e9190614cc8565b612d989190614cc8565b612da29190614cc8565b90505f612db0600186614cb5565b612dbb90600261546a565b612dc690600261546a565b612dd1906006614cc8565b90505f85845f0151612de3919061546a565b905081868560200151612df6919061546a565b612e00919061546a565b612e0a9082614cc8565b90506001861115612e52576002612e22600188614cb5565b612e2c908861546a565b8560400151612e3b919061546a565b612e459190615481565b612e4f9082614cc8565b90505b81868560c00151612e63919061546a565b612e6d919061546a565b612e779082614cc8565b905082868560600151612e8a919061546a565b612e94919061546a565b612e9e9082614cc8565b9050848460800151612eb0919061546a565b612eba9082614cc8565b90506001851115612f02576002612ed2600187614cb5565b612edc908761546a565b8560400151612eeb919061546a565b612ef59190615481565b612eff9082614cc8565b90505b60a0840151612f119082614cc8565b61010085015190915061271090612f2c9061ffff1682614cc8565b612f36908361546a565b612f409190615481565b97508780612f6457604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b612f79613712565b6001600160a01b03811615801590612f9f57506001546001600160a01b03828116911614155b8190612fbf576040516320252f0b60e01b8152600401610a84919061460c565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac90839061460c565b613013613712565b613020602082018261522e565b63ffffffff16613036604083016020840161522e565b63ffffffff161015801561305b57505f613053602083018361522e565b63ffffffff16115b61309b5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156131a45761014081015163ffffffff16613155604084016020850161522e565b63ffffffff1610156131a45760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff16156132185761016081015163ffffffff166131ce602084018461522e565b63ffffffff1610156132185760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f85600381111561322e5761322e614670565b600381111561323f5761323f614670565b815260208101919091526040015f206132599160026142bd565b5082600381111561326c5761326c614670565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161329b91906154a0565b60405180910390a2505050565b6132b0613712565b6001600160a01b0381166132d9575f604051631e4fbdf760e01b8152600401610a84919061460c565b610bc8816137b1565b5f818152600d602052604081205460ff168181600681111561330657613306614670565b0361332b57826001826040516337e1404160e01b8152600401610a849392919061502b565b600581600681111561333f5761333f614670565b036133605760405163462c7bed60e01b815260048101849052602401610a84565b600681600681111561337457613374614670565b0361339557604051633de16e3560e11b815260048101849052602401610a84565b5f6133a08483613d9d565b93509050806133c557604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561340e5761340e614670565b0217905550835f51602061565d5f395f51905f52836006604051613433929190614f66565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161346d9291906154e0565b60405180910390a25050919050565b613484613712565b6001600160a01b038116158015906134a957505f546001600160a01b03828116911614155b81906134c9576040516375ac4eb760e11b8152600401610a84919061460c565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac90839061460c565b6001600160a01b0381165f90815260076020526040902054819060ff16156135505760405163b29d459560e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac90839061460c565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6135d5614080565b610bc8816140a5565b80356136215760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f81602001351161366d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116136bc5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b3361371b611f6b565b6001600160a01b031614611a31573360405163118cdaa760e01b8152600401610a84919061460c565b6040516001600160a01b0384811660248301528381166044830152606482018390526137ab9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506140ad565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613866573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261388d91908101906154fb565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361392b576002546040516341489f1560e01b81526001600160a01b03909116906341489f15906138f79088908890869060040161558a565b5f604051808303815f87803b15801561390e575f5ffd5b505af1158015613920573d5f5f3e3d5ffd5b505050505050505050565b825f036139cc575f858152601060205260409020546001600160a01b03168015613963576139636001600160a01b0383168285613d72565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906139979089908990879060040161558a565b5f604051808303815f87803b1580156139ae575f5ffd5b505af11580156139c0573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156139e5576139e56143bf565b604051908082528060200260200182016040528015613a0e578160200160208202803683370190505b50601d549091505f9061ffff600160b01b820416906001600160a01b03168115801590613a4357506001600160a01b03811615155b15613a7f57612710613a5961ffff84168861546a565b613a639190615481565b92508215613a7f57613a7f6001600160a01b0386168285613d72565b5f613a8a8488614cb5565b90505f613a978983615481565b90505f805b8a811015613ad65782888281518110613ab757613ab7614c7f565b6020908102919091010152613acc8383614cc8565b9150600101613a9c565b505f613ae28285614cb5565b90508015613b1f578088613af760018e614cb5565b81518110613b0757613b07614c7f565b60200260200101818151613b1b9190614cc8565b9052505b600154613b39906001600160a01b038b8116911686614110565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e8b6040518463ffffffff1660e01b8152600401613b7d939291906155ea565b5f604051808303815f87803b158015613b94575f5ffd5b505af1158015613ba6573d5f5f3e3d5ffd5b5050600154613bc492506001600160a01b038c81169250165f614110565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8a604051613bf692919061561f565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613c429392919061558a565b5f604051808303815f87803b158015613c59575f5ffd5b505af1158015613c6b573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613ca657613ca6614670565b1480613cc35750600281600d811115613cc157613cc1614670565b145b15613cfb575f5b604051908082528060200260200182016040528015613cf3578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613d6157506040513d5f823e601f3d908101601f19168201604052613d5e91908101906154fb565b60015b613d6b575f613cca565b9392505050565b613d9883846001600160a01b031663a9059cbb8585604051602401613779929190615643565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613e17573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e3b9190614ddb565b90506001856006811115613e5157613e51614670565b148015613e5d57508042115b15613e7057600180935093505050613f1e565b6002856006811115613e8457613e84614670565b148015613e915750815142115b15613ea55760016003935093505050613f1e565b6003856006811115613eb957613eb9614670565b148015613ec95750816020015142115b15613edd5760016006935093505050613f1e565b6004856006811115613ef157613ef1614670565b148015613f015750816040015142115b15613f15576001600a935093505050613f1e565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff1690816006811115613f4957613f49614670565b03613f6e57826001826040516337e1404160e01b8152600401610a849392919061502b565b6005816006811115613f8257613f82614670565b03613fa35760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613fb757613fb7614670565b03613fd857604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561402157614021614670565b0217905550825f51602061565d5f395f51905f52826006604051614046929190614f66565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161329b9291906154e0565b6140886141a0565b611a3157604051631afcd79f60e31b815260040160405180910390fd5b6132b0614080565b5f5f60205f8451602086015f885af1806140cc576040513d5f823e3d81fd5b50505f513d915081156140e35780600114156140f0565b6001600160a01b0384163b155b156137ab5783604051635274afe760e01b8152600401610a84919061460c565b5f836001600160a01b031663095ea7b38484604051602401614133929190615643565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061416c84826141b9565b6137ab5761419684856001600160a01b031663095ea7b3865f604051602401613779929190615643565b6137ab84826140ad565b5f6141a96135a3565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156141f8575081156141ea57806001146141f8565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161422a614359565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156142ad579160200282015b828111156142ad578251825591602001919060010190614292565b506142b9929150614377565b5090565b6001830191839082156142ad579160200282015f5b8382111561431c57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026142d2565b801561434c5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261431c565b50506142b9929150614377565b60405180604001604052806002906020820280368337509192915050565b5b808211156142b9575f8155600101614378565b6001600160a01b0381168114610bc8575f5ffd5b80356143aa8161438b565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156143fb576143fb6143bf565b604052919050565b5f6001600160401b0382111561441b5761441b6143bf565b5060051b60200190565b5f82601f830112614434575f5ffd5b81356001600160401b0381111561444d5761444d6143bf565b614460601f8201601f19166020016143d3565b818152846020838601011115614474575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f83011261449f575f5ffd5b81356144b26144ad82614403565b6143d3565b8082825260208201915060208360051b8601019250858311156144d3575f5ffd5b602085015b838110156145135780356001600160401b038111156144f5575f5ffd5b614504886020838a0101614425565b845250602092830192016144d8565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614535575f5ffd5b88356145408161438b565b975060208901356145508161438b565b965060408901356145608161438b565b955060608901356145708161438b565b945060808901356145808161438b565b935060a089013592506145968a60c08b016143af565b91506101208901356001600160401b038111156145b1575f5ffd5b6145bd8b828c01614490565b9150509295985092959890939650565b5f602082840312156145dd575f5ffd5b8135613d6b8161438b565b5f602082840312156145f8575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106143aa575f5ffd5b5f5f6040838503121561463f575f5ffd5b61464883614620565b946020939093013593505050565b5f60608284031215614666575f5ffd5b613d6b83836143af565b634e487b7160e01b5f52602160045260245ffd5b600e811061469457614694614670565b9052565b602081016135c78284614684565b6004811061469457614694614670565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526146f4602082018f6146a6565b8c60408201528b606082015261470d608082018c6145ff565b6101c060a08201525f6147246101c083018c6146b6565b82810360c0840152614736818c6146b6565b905061474560e084018b6145ff565b61475361010084018a6145ff565b876101208401528661014084015282810361016084015261477481876146b6565b9150506147856101808301856145ff565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156137ab5781518452602093840193909101906001016147a4565b805182525f60208201516147da60208501826146a6565b506040820151604084015260608201516147f760608501826147a1565b50608082015160a084015260a082015161481460c08501826145ff565b5060c082015161020060e08501526148306102008501826146b6565b905060e083015184820361010086015261484a82826146b6565b9150506101008301516148616101208601826145ff565b506101208301516148766101408601826145ff565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148a882826146b6565b9150506101a08301516148bf6101c08601826145ff565b506101c08301518015156101e0860152613cf3565b602081525f613d6b60208301846147c3565b5f602082840312156148f6575f5ffd5b81356001600160401b0381111561490b575f5ffd5b61491784828501614425565b949350505050565b5f6020828403121561492f575f5ffd5b81356001600160401b03811115614944575f5ffd5b82016101008185031215613d6b575f5ffd5b828152604060208201525f61491760408301846147c3565b5f6020828403121561497e575f5ffd5b81356001600160401b03811115614993575f5ffd5b61491784828501614490565b5f5f604083850312156149b0575f5ffd5b8235915060208301356149c28161438b565b809150509250929050565b5f5f83601f8401126149dd575f5ffd5b5081356001600160401b038111156149f3575f5ffd5b602083019150836020828501011115613f1e575f5ffd5b5f5f5f5f5f60608688031215614a1e575f5ffd5b8535945060208601356001600160401b03811115614a3a575f5ffd5b614a46888289016149cd565b90955093505060408601356001600160401b03811115614a64575f5ffd5b614a70888289016149cd565b969995985093965092949392505050565b5f5f60408385031215614a92575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016135c7565b821515815260408101613d6b6020830184614684565b5f610180828403128015614aea575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614b4c60e08401826145ff565b50610100830151614b6461010084018261ffff169052565b50610120830151614b7c61012084018261ffff169052565b50610140830151614b9661014084018263ffffffff169052565b50610160830151614bb061016084018263ffffffff169052565b5092915050565b5f5f60408385031215614bc8575f5ffd5b82359150602083013560ff811681146149c2575f5ffd5b6007811061469457614694614670565b602081016135c78284614bdf565b5f5f60608385031215614c0e575f5ffd5b614c1783614620565b915083606084011115614c28575f5ffd5b50926020919091019150565b600181811c90821680614c4857607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614c76575f5ffd5b613d6b82614620565b634e487b7160e01b5f52603260045260245ffd5b602081016135c782846146a6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156135c7576135c7614ca1565b808201808211156135c7576135c7614ca1565b5f60018201614cec57614cec614ca1565b5060010190565b5f5f8335601e19843603018112614d08575f5ffd5b8301803591506001600160401b03821115614d21575f5ffd5b602001915036819003821315613f1e575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614d52575f5ffd5b8135613d6b81614d35565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614da460a08301888a614d5d565b8281036060840152614db7818789614d5d565b90508281036080840152614dcc818587614d5d565b9b9a5050505050505050505050565b5f60208284031215614deb575f5ffd5b5051919050565b601f821115613d9857805f5260205f20601f840160051c81016020851015614e175750805b601f840160051c820191505b81811015614e36575f8155600101614e23565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115614e6a57614e6a6143bf565b614e7e81614e788454614c34565b84614df2565b6020601f821160018114614eab575f8315614e995750848201515b614ea38482614e3d565b855550614e36565b5f84815260208120601f198516915b82811015614eda5787850151825560209485019460019092019101614eba565b5084821015614ef757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b6002811015614f4057815163ffffffff16835260209283019290910190600101614f1b565b505050949350505050565b5f60208284031215614f5b575f5ffd5b8151613d6b81614d35565b60408101614f748285614bdf565b613d6b6020830184614bdf565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015614fee57603f19878603018452614fd98583516146b6565b94506020938401939190910190600101614fbd565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161503f6020830185614bdf565b6149176040830184614bdf565b6001600160401b03831115615063576150636143bf565b615077836150718354614c34565b83614df2565b5f601f8411600181146150a3575f85156150915750838201355b61509b8682614e3d565b845550614e36565b5f83815260208120601f198716915b828110156150d257868501358255602094850194600190920191016150b2565b50868210156150ee575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f615128604083018486614d5d565b95945050505050565b602081525f614917602083018486614d5d565b5f8151808452602084019350602083015f5b8281101561517d5781516001600160a01b0316865260209586019590910190600101615156565b5093949350505050565b848152836020820152608060408201525f6151a56080830185615144565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f6141f8606083018486614d5d565b61ffff81168114610bc8575f5ffd5b80356143aa816151dd565b5f60208284031215615207575f5ffd5b8135613d6b816151dd565b63ffffffff81168114610bc8575f5ffd5b80356143aa81615212565b5f6020828403121561523e575f5ffd5b8135613d6b81615212565b5f81356135c78161438b565b5f81356135c7816151dd565b5f81356135c781615212565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152dd6152c060e08501615249565b82546001600160a01b0319166001600160a01b0391909116178255565b61530d6152ed6101008501615255565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61533d61531d6101208501615255565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61537161534d6101408501615261565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613d986153816101608501615261565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016153f660e0840161439f565b61540360e08401826145ff565b5061541161010084016151ec565b61ffff1661010083015261542861012084016151ec565b61ffff1661012083015261543f6101408401615223565b63ffffffff166101408301526154586101608401615223565b63ffffffff8116610160840152614bb0565b80820281158282048414176135c7576135c7614ca1565b5f8261549b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156154d75781356154bc81615212565b63ffffffff16835260209283019291909101906001016154a8565b50505092915050565b604081016154ee8285614bdf565b613d6b6020830184614684565b5f6020828403121561550b575f5ffd5b81516001600160401b03811115615520575f5ffd5b8201601f81018413615530575f5ffd5b805161553e6144ad82614403565b8082825260208201915060208360051b85010192508683111561555f575f5ffd5b6020840193505b828410156141f85783516155798161438b565b825260209384019390910190615566565b838152606060208201525f6155a26060830185615144565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561517d5781518652602095860195909101906001016155cc565b6001600160a01b03841681526060602082018190525f9061560d90830185615144565b82810360408401526141f881856155ba565b604081525f6156316040830185615144565b828103602084015261512881856155ba565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c806390173a4111610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a0d4664f1161013c578063a0d4664f14610641578063a87f4ab914610654578063ac3d2f4214610669578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b806390173a41146105aa5780639117173c146105bf57806392312386146105d2578063929a8faf146105e557806399c6679d146106065780639c8570c81461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d74146105315780637edcd7ab1461054457806381476ec214610557578063858142431461056a5780638da5cb5b1461057d5780638dcdd86b146105855780638e5ce3ad14610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461451d565b61081d565b005b6102f06103003660046145cd565b610a2a565b61032d6103133660046145e8565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061460c565b60405180910390f35b61032d6103513660046145e8565b60096020525f90815260409020546001600160a01b031681565b61037e61037936600461462e565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a13660046145cd565b610b12565b6102f06103b4366004614656565b610bb7565b6103db6103c73660046145e8565b5f908152600f602052604090205460ff1690565b60405161033a9190614698565b6103fb6103f63660046145e8565b610bcb565b60405161033a9e9d9c9b9a999897969594939291906146e4565b6104286104233660046145e8565b610df5565b60405161033a91906148d4565b6104546104433660046145e8565b600c6020525f908152604090205481565b60405190815260200161033a565b6104906104703660046148e6565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046145e8565b6110f2565b6102f06104c13660046145cd565b611181565b6104d96104d436600461491f565b611214565b60405161033a929190614956565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a20565b6102f061051936600461496e565b611a33565b6102f061052c36600461499f565b611acb565b6102f061053f3660046145e8565b611b54565b610490610552366004614a0a565b611c52565b6102f0610565366004614a81565b611e78565b60015461032d906001600160a01b031681565b61032d611f6b565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b6105b2611f99565b60405161033a9190614aa1565b6102f06105cd3660046145e8565b611fdf565b6105b26105e03660046145e8565b612187565b6105f86105f33660046145e8565b6121e0565b60405161033a929190614ac2565b61032d6106143660046145e8565b5f908152601060205260409020546001600160a01b031690565b61049061063c366004614a0a565b612207565b6102f061064f366004614ad8565b61249f565b61065c6126c0565b60405161033a9190614af2565b61032d6106773660046145e8565b5f908152600a60205260409020546001600160a01b031690565b6102f061069f36600461496e565b6127d0565b6102f06106b2366004614bb7565b612867565b6102f06106c53660046145cd565b612952565b6102f06106d8366004614a81565b6129f9565b6104906106eb3660046145cd565b60076020525f908152604090205460ff1681565b61045460065481565b6102f061071636600461499f565b612adc565b6102f06107293660046145e8565b612b8f565b61075061073c3660046145e8565b5f908152600d602052604090205460ff1690565b60405161033a9190614bef565b61045461076b36600461491f565b612bcc565b6102f061077e3660046145cd565b612f71565b6102f0610791366004614bfd565b61300b565b60025461032d906001600160a01b031681565b6102f06107b73660046145cd565b6132a8565b6103db6107ca3660046145e8565b6132e2565b6102f06107dd3660046145cd565b61347c565b61032d6107f03660046145e8565b600a6020525f90815260409020546001600160a01b031681565b6102f06108183660046145cd565b613514565b5f6108266135a3565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336135cd565b6108cf88612b8f565b6108d88c61347c565b6108e18b612f71565b6108ea8a610a2a565b6108f389610b12565b6108fc876135de565b610905866127d0565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601694909455601792909255601894909455601993909355601a92909255601b91909155601c55607d60a31b601d556109b4611f6b565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6132a8565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613712565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613712565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a84919061460c565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac90839061460c565b60405180910390a150565b610bbf613712565b610bc8816135de565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614c34565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614c34565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614c34565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614202565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a614670565b6003811115610e4b57610e4b614670565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614c34565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614c34565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614c34565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613712565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613712565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac90839061460c565b5f61121d614202565b5f60128161122e6020870187614c66565b600381111561123f5761123f614670565b600381111561125057611250614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614c7f565b602002015163ffffffff1611845f0160208101906112ec9190614c66565b9061130b5760405163286c068d60e11b8152600401610a849190614c93565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506015546014545f919061137b426040890135614cb5565b6113859190614cc8565b61138f9190614cc8565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc60808801606089016145cd565b6001600160a01b0316815260208101919091526040015f205460ff166113f860808701606088016145cd565b906114175760405163295a6a6f60e11b8152600401610a84919061460c565b505f61142286612bcc565b60068054965090915085905f61143783614cdb565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506114d69190890135614cc8565b5f878152600e60209081526040909120600101919091558186526114fc90880188614c66565b8560200190600381111561151257611512614670565b9081600381111561152557611525614670565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261156d90608089019089016145cd565b6001600160a01b031660a08601526115886080880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526115d090880188614cf3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261161d906101008901908901614d42565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a0860181905260045461166d916001600160a01b03909116903085613744565b5f61167e6080890160608a016145cd565b6001600160a01b031663fefd9a8b888461169b60808d018d614cf3565b6116a860a08f018f614cf3565b8f8060c001906116b89190614cf3565b6040518963ffffffff1660e01b81526004016116db989796959493929190614d85565b6020604051808303815f875af11580156116f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061171b9190614ddb565b5f818152600960205260409020549091506001600160a01b03168181611757576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b03168281611791576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156117ef576117ef614670565b02179055506040820151816002015560608201518160030190600261181592919061427f565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c0820151600782019061185a9082614e51565b5060e0820151600882019061186f9082614e51565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906118d79082614e51565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b9061193d908c9088908c90600401614f06565b6020604051808303815f875af1158015611959573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197d9190614f4b565b61199a57604051630d8dbe2560e01b815260040160405180910390fd5b6119aa60808b0160608c016145cd565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516119e4929190614956565b60405180910390a2885f51602061565d5f395f51905f525f6001604051611a0c929190614f66565b60405180910390a250505050505050915091565b611a28613712565b611a315f6137b1565b565b611a3b613712565b80515f5b81811015611a8f57600b838281518110611a5b57611a5b614c7f565b6020026020010151604051611a709190614f81565b908152604051908190036020019020805460ff19169055600101611a3f565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611abf9190614f97565b60405180910390a15050565b611ad3613712565b6001600160a01b03811615801590611b0457505f828152600a60205260409020546001600160a01b03828116911614155b8290611b26576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610a8490614ffa565b5f818152600d602052604090205460ff166001816006811115611ba257611ba2614670565b14611bc757816001826040516337e1404160e01b8152600401610a849392919061502b565b5f828152600d60205260409020805460ff19166002179055601354611bec9042614cc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061565d5f395f51905f5260016002604051611c46929190614f66565b60405180910390a25050565b5f5f611c5d87610df5565b5f888152600d602052604090205490915060ff166004816006811115611c8557611c85614670565b1488600483909192611cad576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611d10576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f898152600860205260409020600d01611d2d888a8361504c565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611d71929190615100565b6040519081900381206001600160e01b031960e084901b168252611d9b918a908a9060040161510f565b602060405180830381865afa158015611db6573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dda9190614f4b565b9350878785611dfe57604051632f9f8ab960e01b8152600401610a84929190615131565b5050611e0989613821565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611e3b929190615131565b60405180910390a2885f51602061565d5f395f51905f5260046005604051611e64929190614f66565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611ea15760405162461bcd60e51b8152600401610a8490614ffa565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ed157611ed1614670565b14611ef657836002826040516337e1404160e01b8152600401610a849392919061502b565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061565d5f395f51905f5260026003604051611f5d929190614f66565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611fba60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff16600681600681111561200457612004614670565b146120415760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c6020526040902054806120935760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c602052604081208190556120ac84613c7e565b5f858152601160205260409020546002549192506001600160a01b03908116916120d99183911685613d72565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061210f908890879087908790600401615187565b5f604051808303815f87803b158015612126575f5ffd5b505af1158015612138573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612178929190918252602082015260400190565b60405180910390a25050505050565b6121a860405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121fd8482613d9d565b9250925050915091565b5f5f61221287610df5565b5f888152600d602052604090205490915060ff16600381600681111561223a5761223a614670565b1488600383909192612262576040516337e1404160e01b8152600401610a849392919061502b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156122c6576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156122fd5760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561232857604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161233a929190615100565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061237c9042614cc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906123c9908d9085908c908c906004016151be565b6020604051808303815f875af11580156123e5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124099190614f4b565b945088888661242d57604051632f9f8ab960e01b8152600401610a84929190615131565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051612461929190615131565b60405180910390a2895f51602061565d5f395f51905f526003600460405161248a929190614f66565b60405180910390a25050505095945050505050565b6124a7613712565b6127106124bc610120830161010084016151f7565b61ffff1611156125045760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b612710612519610140830161012084016151f7565b61ffff1611156125605760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612572610140820161012083016151f7565b61ffff16158061259b57505f61258f610100830160e084016145cd565b6001600160a01b031614155b6125f95760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61260b6101808201610160830161522e565b63ffffffff166126236101608301610140840161522e565b63ffffffff1610156126815760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b80601661268e828261526d565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906153a5565b6127356040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b6127d8613712565b80515f5b81811015612837576001600b8483815181106127fa576127fa614c7f565b602002602001015160405161280f9190614f81565b908152604051908190036020019020805491151560ff199092169190911790556001016127dc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611abf9190614f97565b5f546001600160a01b031633148061288957506003546001600160a01b031633145b6128d55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff161180156128eb5750600d60ff821611155b6129305760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b61294e828260ff16600d81111561294957612949614670565b613f25565b5050565b61295a613712565b6001600160a01b0381166129b05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a4a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612a94575f5ffd5b505af1158015612aa6573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c4691815260200190565b612ae4613712565b6001600160a01b03811615801590612b1557505f828152600960205260409020546001600160a01b03828116911614155b8290612b37576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611abf565b612b97613712565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612bde6020860186614c66565b6003811115612bef57612bef614670565b6003811115612c0057612c00614670565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c27579050505050505090505f81600160028110612c7e57612c7e614c7f565b602002015163ffffffff1611835f016020810190612c9c9190614c66565b90612cbb5760405163286c068d60e11b8152600401610a849190614c93565b5060208181015182516040805161018081018252601654815260175481860152601854818301526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b909104811661016083015260155460145460135496831697929095169592945f94919390929091612d84918c0135908c0135614cb5565b612d8e9190614cc8565b612d989190614cc8565b612da29190614cc8565b90505f612db0600186614cb5565b612dbb90600261546a565b612dc690600261546a565b612dd1906006614cc8565b90505f85845f0151612de3919061546a565b905081868560200151612df6919061546a565b612e00919061546a565b612e0a9082614cc8565b90506001861115612e52576002612e22600188614cb5565b612e2c908861546a565b8560400151612e3b919061546a565b612e459190615481565b612e4f9082614cc8565b90505b81868560c00151612e63919061546a565b612e6d919061546a565b612e779082614cc8565b905082868560600151612e8a919061546a565b612e94919061546a565b612e9e9082614cc8565b9050848460800151612eb0919061546a565b612eba9082614cc8565b90506001851115612f02576002612ed2600187614cb5565b612edc908761546a565b8560400151612eeb919061546a565b612ef59190615481565b612eff9082614cc8565b90505b60a0840151612f119082614cc8565b61010085015190915061271090612f2c9061ffff1682614cc8565b612f36908361546a565b612f409190615481565b97508780612f6457604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b612f79613712565b6001600160a01b03811615801590612f9f57506001546001600160a01b03828116911614155b8190612fbf576040516320252f0b60e01b8152600401610a84919061460c565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac90839061460c565b613013613712565b613020602082018261522e565b63ffffffff16613036604083016020840161522e565b63ffffffff161015801561305b57505f613053602083018361522e565b63ffffffff16115b61309b5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260165481526017546020820152601854918101919091526019546060820152601a546080820152601b5460a0820152601c5460c0820152601d546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156131a45761014081015163ffffffff16613155604084016020850161522e565b63ffffffff1610156131a45760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff16156132185761016081015163ffffffff166131ce602084018461522e565b63ffffffff1610156132185760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f85600381111561322e5761322e614670565b600381111561323f5761323f614670565b815260208101919091526040015f206132599160026142bd565b5082600381111561326c5761326c614670565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161329b91906154a0565b60405180910390a2505050565b6132b0613712565b6001600160a01b0381166132d9575f604051631e4fbdf760e01b8152600401610a84919061460c565b610bc8816137b1565b5f818152600d602052604081205460ff168181600681111561330657613306614670565b0361332b57826001826040516337e1404160e01b8152600401610a849392919061502b565b600581600681111561333f5761333f614670565b036133605760405163462c7bed60e01b815260048101849052602401610a84565b600681600681111561337457613374614670565b0361339557604051633de16e3560e11b815260048101849052602401610a84565b5f6133a08483613d9d565b93509050806133c557604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561340e5761340e614670565b0217905550835f51602061565d5f395f51905f52836006604051613433929190614f66565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161346d9291906154e0565b60405180910390a25050919050565b613484613712565b6001600160a01b038116158015906134a957505f546001600160a01b03828116911614155b81906134c9576040516375ac4eb760e11b8152600401610a84919061460c565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac90839061460c565b6001600160a01b0381165f90815260076020526040902054819060ff16156135505760405163b29d459560e01b8152600401610a84919061460c565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac90839061460c565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6135d5614080565b610bc8816140a5565b80356136215760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f81602001351161366d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116136bc5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b3361371b611f6b565b6001600160a01b031614611a31573360405163118cdaa760e01b8152600401610a84919061460c565b6040516001600160a01b0384811660248301528381166044830152606482018390526137ab9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506140ad565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613866573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261388d91908101906154fb565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361392b576002546040516341489f1560e01b81526001600160a01b03909116906341489f15906138f79088908890869060040161558a565b5f604051808303815f87803b15801561390e575f5ffd5b505af1158015613920573d5f5f3e3d5ffd5b505050505050505050565b825f036139cc575f858152601060205260409020546001600160a01b03168015613963576139636001600160a01b0383168285613d72565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906139979089908990879060040161558a565b5f604051808303815f87803b1580156139ae575f5ffd5b505af11580156139c0573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156139e5576139e56143bf565b604051908082528060200260200182016040528015613a0e578160200160208202803683370190505b50601d549091505f9061ffff600160b01b820416906001600160a01b03168115801590613a4357506001600160a01b03811615155b15613a7f57612710613a5961ffff84168861546a565b613a639190615481565b92508215613a7f57613a7f6001600160a01b0386168285613d72565b5f613a8a8488614cb5565b90505f613a978983615481565b90505f805b8a811015613ad65782888281518110613ab757613ab7614c7f565b6020908102919091010152613acc8383614cc8565b9150600101613a9c565b505f613ae28285614cb5565b90508015613b1f578088613af760018e614cb5565b81518110613b0757613b07614c7f565b60200260200101818151613b1b9190614cc8565b9052505b600154613b39906001600160a01b038b8116911686614110565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e8b6040518463ffffffff1660e01b8152600401613b7d939291906155ea565b5f604051808303815f87803b158015613b94575f5ffd5b505af1158015613ba6573d5f5f3e3d5ffd5b5050600154613bc492506001600160a01b038c81169250165f614110565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8a604051613bf692919061561f565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613c429392919061558a565b5f604051808303815f87803b158015613c59575f5ffd5b505af1158015613c6b573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613ca657613ca6614670565b1480613cc35750600281600d811115613cc157613cc1614670565b145b15613cfb575f5b604051908082528060200260200182016040528015613cf3578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613d6157506040513d5f823e601f3d908101601f19168201604052613d5e91908101906154fb565b60015b613d6b575f613cca565b9392505050565b613d9883846001600160a01b031663a9059cbb8585604051602401613779929190615643565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613e17573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e3b9190614ddb565b90506001856006811115613e5157613e51614670565b148015613e5d57508042115b15613e7057600180935093505050613f1e565b6002856006811115613e8457613e84614670565b148015613e915750815142115b15613ea55760016003935093505050613f1e565b6003856006811115613eb957613eb9614670565b148015613ec95750816020015142115b15613edd5760016006935093505050613f1e565b6004856006811115613ef157613ef1614670565b148015613f015750816040015142115b15613f15576001600a935093505050613f1e565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff1690816006811115613f4957613f49614670565b03613f6e57826001826040516337e1404160e01b8152600401610a849392919061502b565b6005816006811115613f8257613f82614670565b03613fa35760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613fb757613fb7614670565b03613fd857604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561402157614021614670565b0217905550825f51602061565d5f395f51905f52826006604051614046929190614f66565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161329b9291906154e0565b6140886141a0565b611a3157604051631afcd79f60e31b815260040160405180910390fd5b6132b0614080565b5f5f60205f8451602086015f885af1806140cc576040513d5f823e3d81fd5b50505f513d915081156140e35780600114156140f0565b6001600160a01b0384163b155b156137ab5783604051635274afe760e01b8152600401610a84919061460c565b5f836001600160a01b031663095ea7b38484604051602401614133929190615643565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061416c84826141b9565b6137ab5761419684856001600160a01b031663095ea7b3865f604051602401613779929190615643565b6137ab84826140ad565b5f6141a96135a3565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156141f8575081156141ea57806001146141f8565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161422a614359565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156142ad579160200282015b828111156142ad578251825591602001919060010190614292565b506142b9929150614377565b5090565b6001830191839082156142ad579160200282015f5b8382111561431c57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026142d2565b801561434c5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261431c565b50506142b9929150614377565b60405180604001604052806002906020820280368337509192915050565b5b808211156142b9575f8155600101614378565b6001600160a01b0381168114610bc8575f5ffd5b80356143aa8161438b565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156143fb576143fb6143bf565b604052919050565b5f6001600160401b0382111561441b5761441b6143bf565b5060051b60200190565b5f82601f830112614434575f5ffd5b81356001600160401b0381111561444d5761444d6143bf565b614460601f8201601f19166020016143d3565b818152846020838601011115614474575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f83011261449f575f5ffd5b81356144b26144ad82614403565b6143d3565b8082825260208201915060208360051b8601019250858311156144d3575f5ffd5b602085015b838110156145135780356001600160401b038111156144f5575f5ffd5b614504886020838a0101614425565b845250602092830192016144d8565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614535575f5ffd5b88356145408161438b565b975060208901356145508161438b565b965060408901356145608161438b565b955060608901356145708161438b565b945060808901356145808161438b565b935060a089013592506145968a60c08b016143af565b91506101208901356001600160401b038111156145b1575f5ffd5b6145bd8b828c01614490565b9150509295985092959890939650565b5f602082840312156145dd575f5ffd5b8135613d6b8161438b565b5f602082840312156145f8575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106143aa575f5ffd5b5f5f6040838503121561463f575f5ffd5b61464883614620565b946020939093013593505050565b5f60608284031215614666575f5ffd5b613d6b83836143af565b634e487b7160e01b5f52602160045260245ffd5b600e811061469457614694614670565b9052565b602081016135c78284614684565b6004811061469457614694614670565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526146f4602082018f6146a6565b8c60408201528b606082015261470d608082018c6145ff565b6101c060a08201525f6147246101c083018c6146b6565b82810360c0840152614736818c6146b6565b905061474560e084018b6145ff565b61475361010084018a6145ff565b876101208401528661014084015282810361016084015261477481876146b6565b9150506147856101808301856145ff565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156137ab5781518452602093840193909101906001016147a4565b805182525f60208201516147da60208501826146a6565b506040820151604084015260608201516147f760608501826147a1565b50608082015160a084015260a082015161481460c08501826145ff565b5060c082015161020060e08501526148306102008501826146b6565b905060e083015184820361010086015261484a82826146b6565b9150506101008301516148616101208601826145ff565b506101208301516148766101408601826145ff565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148a882826146b6565b9150506101a08301516148bf6101c08601826145ff565b506101c08301518015156101e0860152613cf3565b602081525f613d6b60208301846147c3565b5f602082840312156148f6575f5ffd5b81356001600160401b0381111561490b575f5ffd5b61491784828501614425565b949350505050565b5f6020828403121561492f575f5ffd5b81356001600160401b03811115614944575f5ffd5b82016101008185031215613d6b575f5ffd5b828152604060208201525f61491760408301846147c3565b5f6020828403121561497e575f5ffd5b81356001600160401b03811115614993575f5ffd5b61491784828501614490565b5f5f604083850312156149b0575f5ffd5b8235915060208301356149c28161438b565b809150509250929050565b5f5f83601f8401126149dd575f5ffd5b5081356001600160401b038111156149f3575f5ffd5b602083019150836020828501011115613f1e575f5ffd5b5f5f5f5f5f60608688031215614a1e575f5ffd5b8535945060208601356001600160401b03811115614a3a575f5ffd5b614a46888289016149cd565b90955093505060408601356001600160401b03811115614a64575f5ffd5b614a70888289016149cd565b969995985093965092949392505050565b5f5f60408385031215614a92575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016135c7565b821515815260408101613d6b6020830184614684565b5f610180828403128015614aea575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614b4c60e08401826145ff565b50610100830151614b6461010084018261ffff169052565b50610120830151614b7c61012084018261ffff169052565b50610140830151614b9661014084018263ffffffff169052565b50610160830151614bb061016084018263ffffffff169052565b5092915050565b5f5f60408385031215614bc8575f5ffd5b82359150602083013560ff811681146149c2575f5ffd5b6007811061469457614694614670565b602081016135c78284614bdf565b5f5f60608385031215614c0e575f5ffd5b614c1783614620565b915083606084011115614c28575f5ffd5b50926020919091019150565b600181811c90821680614c4857607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614c76575f5ffd5b613d6b82614620565b634e487b7160e01b5f52603260045260245ffd5b602081016135c782846146a6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156135c7576135c7614ca1565b808201808211156135c7576135c7614ca1565b5f60018201614cec57614cec614ca1565b5060010190565b5f5f8335601e19843603018112614d08575f5ffd5b8301803591506001600160401b03821115614d21575f5ffd5b602001915036819003821315613f1e575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614d52575f5ffd5b8135613d6b81614d35565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614da460a08301888a614d5d565b8281036060840152614db7818789614d5d565b90508281036080840152614dcc818587614d5d565b9b9a5050505050505050505050565b5f60208284031215614deb575f5ffd5b5051919050565b601f821115613d9857805f5260205f20601f840160051c81016020851015614e175750805b601f840160051c820191505b81811015614e36575f8155600101614e23565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115614e6a57614e6a6143bf565b614e7e81614e788454614c34565b84614df2565b6020601f821160018114614eab575f8315614e995750848201515b614ea38482614e3d565b855550614e36565b5f84815260208120601f198516915b82811015614eda5787850151825560209485019460019092019101614eba565b5084821015614ef757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b6002811015614f4057815163ffffffff16835260209283019290910190600101614f1b565b505050949350505050565b5f60208284031215614f5b575f5ffd5b8151613d6b81614d35565b60408101614f748285614bdf565b613d6b6020830184614bdf565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015614fee57603f19878603018452614fd98583516146b6565b94506020938401939190910190600101614fbd565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161503f6020830185614bdf565b6149176040830184614bdf565b6001600160401b03831115615063576150636143bf565b615077836150718354614c34565b83614df2565b5f601f8411600181146150a3575f85156150915750838201355b61509b8682614e3d565b845550614e36565b5f83815260208120601f198716915b828110156150d257868501358255602094850194600190920191016150b2565b50868210156150ee575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f615128604083018486614d5d565b95945050505050565b602081525f614917602083018486614d5d565b5f8151808452602084019350602083015f5b8281101561517d5781516001600160a01b0316865260209586019590910190600101615156565b5093949350505050565b848152836020820152608060408201525f6151a56080830185615144565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f6141f8606083018486614d5d565b61ffff81168114610bc8575f5ffd5b80356143aa816151dd565b5f60208284031215615207575f5ffd5b8135613d6b816151dd565b63ffffffff81168114610bc8575f5ffd5b80356143aa81615212565b5f6020828403121561523e575f5ffd5b8135613d6b81615212565b5f81356135c78161438b565b5f81356135c7816151dd565b5f81356135c781615212565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152dd6152c060e08501615249565b82546001600160a01b0319166001600160a01b0391909116178255565b61530d6152ed6101008501615255565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61533d61531d6101208501615255565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61537161534d6101408501615261565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613d986153816101608501615261565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016153f660e0840161439f565b61540360e08401826145ff565b5061541161010084016151ec565b61ffff1661010083015261542861012084016151ec565b61ffff1661012083015261543f6101408401615223565b63ffffffff166101408301526154586101608401615223565b63ffffffff8116610160840152614bb0565b80820281158282048414176135c7576135c7614ca1565b5f8261549b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156154d75781356154bc81615212565b63ffffffff16835260209283019291909101906001016154a8565b50505092915050565b604081016154ee8285614bdf565b613d6b6020830184614684565b5f6020828403121561550b575f5ffd5b81516001600160401b03811115615520575f5ffd5b8201601f81018413615530575f5ffd5b805161553e6144ad82614403565b8082825260208201915060208360051b85010192508683111561555f575f5ffd5b6020840193505b828410156141f85783516155798161438b565b825260209384019390910190615566565b838152606060208201525f6155a26060830185615144565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561517d5781518652602095860195909101906001016155cc565b6001600160a01b03841681526060602082018190525f9061560d90830185615144565b82810360408401526141f881856155ba565b604081525f6156316040830185615144565b828103602084015261512881856155ba565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615881806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610641578063ac3d2f4214610656578063b27392d51461067e578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a0d4664f1461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614651565b61081d565b005b6102f0610300366004614701565b610a2a565b61032d61031336600461471c565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614740565b60405180910390f35b61032d61035136600461471c565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614762565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a1366004614701565b610b12565b6102f06103b436600461478a565b610bb7565b6103db6103c736600461471c565b5f908152600f602052604090205460ff1690565b60405161033a91906147cc565b6103fb6103f636600461471c565b610bcb565b60405161033a9e9d9c9b9a99989796959493929190614818565b61042861042336600461471c565b610df5565b60405161033a9190614a08565b61045461044336600461471c565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614a1a565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae36600461471c565b6110f2565b6102f06104c1366004614701565b611181565b6104d96104d4366004614a53565b611214565b60405161033a929190614a8a565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a5c565b6102f0610519366004614aa2565b611a6f565b6102f061052c366004614ad3565b611b07565b6102f061053f36600461471c565b611b90565b6102f0610552366004614b01565b611c8e565b60015461032d906001600160a01b031681565b61032d611d81565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611daf565b60405161033a9190614b21565b6102f06105ba36600461471c565b611df5565b61059f6105cd36600461471c565b611f9d565b6105e56105e036600461471c565b611ff6565b60405161033a929190614b42565b61032d61060136600461471c565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614b95565b61201d565b6102f061063c366004614c0c565b6122b5565b6106496124d6565b60405161033a9190614c26565b61032d61066436600461471c565b5f908152600a60205260409020546001600160a01b031690565b61049061068c366004614ceb565b6125e6565b6102f061069f366004614aa2565b612812565b6102f06106b2366004614d90565b6128a9565b6102f06106c5366004614701565b612994565b6102f06106d8366004614b01565b612a3b565b6104906106eb366004614701565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610716366004614ad3565b612b1e565b6102f061072936600461471c565b612bd1565b61075061073c36600461471c565b5f908152600d602052604090205460ff1690565b60405161033a9190614dc8565b61045461076b366004614a53565b612c0e565b6102f061077e366004614701565b613086565b6102f0610791366004614dd6565b613120565b60025461032d906001600160a01b031681565b6102f06107b7366004614701565b6133bd565b6103db6107ca36600461471c565b6133f7565b6102f06107dd366004614701565b613591565b61032d6107f036600461471c565b600a6020525f90815260409020546001600160a01b031681565b6102f0610818366004614701565b613629565b5f6108266136b8565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336136e2565b6108cf88612bd1565b6108d88c613591565b6108e18b613086565b6108ea8a610a2a565b6108f389610b12565b6108fc876136f3565b61090586612812565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601894909455601992909255601a94909455601b93909355601c92909255601d91909155601e55607d60a31b601f556109b4611d81565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6133bd565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613827565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613827565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a849190614740565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac908390614740565b60405180910390a150565b610bbf613827565b610bc8816136f3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614e0d565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614e0d565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614e0d565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614336565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a6147a4565b6003811115610e4b57610e4b6147a4565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614e0d565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614e0d565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614e0d565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613827565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613827565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac908390614740565b5f61121d614336565b5f60128161122e6020870187614e3f565b600381111561123f5761123f6147a4565b6003811115611250576112506147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614e58565b602002015163ffffffff1611845f0160208101906112ec9190614e3f565b9061130b5760405163286c068d60e11b8152600401610a849190614e6c565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016545f919061137b426040890135614e8e565b6113859190614ea1565b61138f9190614ea1565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc6080880160608901614701565b6001600160a01b0316815260208101919091526040015f205460ff166113f86080870160608801614701565b906114175760405163295a6a6f60e11b8152600401610a849190614740565b505f61142286612c0e565b60068054965090915085905f61143783614eb4565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506115129190890135614ea1565b5f878152600e602090815260409091206001019190915581865261153890880188614e3f565b8560200190600381111561154e5761154e6147a4565b90816003811115611561576115616147a4565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526115a99060808901908901614701565b6001600160a01b031660a08601526115c46080880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261160c90880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611659906101008901908901614f1b565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a086018190526004546116a9916001600160a01b03909116903085613859565b5f6116ba6080890160608a01614701565b6001600160a01b031663fefd9a8b88846116d760808d018d614ecc565b6116e460a08f018f614ecc565b8f8060c001906116f49190614ecc565b6040518963ffffffff1660e01b8152600401611717989796959493929190614f5e565b6020604051808303815f875af1158015611733573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117579190614fb4565b5f818152600960205260409020549091506001600160a01b03168181611793576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b031682816117cd576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561182b5761182b6147a4565b0217905550604082015181600201556060820151816003019060026118519291906143b3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611896908261502a565b5060e082015160088201906118ab908261502a565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611913908261502a565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611979908c9088908c906004016150df565b6020604051808303815f875af1158015611995573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b99190615124565b6119d657604051630d8dbe2560e01b815260040160405180910390fd5b6119e660808b0160608c01614701565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611a20929190614a8a565b60405180910390a2885f5160206158555f395f51905f525f6001604051611a4892919061513f565b60405180910390a250505050505050915091565b611a64613827565b611a6d5f6138c6565b565b611a77613827565b80515f5b81811015611acb57600b838281518110611a9757611a97614e58565b6020026020010151604051611aac919061515a565b908152604051908190036020019020805460ff19169055600101611a7b565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611afb9190615170565b60405180910390a15050565b611b0f613827565b6001600160a01b03811615801590611b4057505f828152600a60205260409020546001600160a01b03828116911614155b8290611b62576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611bb95760405162461bcd60e51b8152600401610a84906151d3565b5f818152600d602052604090205460ff166001816006811115611bde57611bde6147a4565b14611c0357816001826040516337e1404160e01b8152600401610a8493929190615204565b5f828152600d60205260409020805460ff19166002179055601554611c289042614ea1565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206158555f395f51905f5260016002604051611c8292919061513f565b60405180910390a25050565b5f546001600160a01b03163314611cb75760405162461bcd60e51b8152600401610a84906151d3565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ce757611ce76147a4565b14611d0c57836002826040516337e1404160e01b8152600401610a8493929190615204565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206158555f395f51905f5260026003604051611d7392919061513f565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611dd060405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611e1a57611e1a6147a4565b14611e575760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c602052604090205480611ea95760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c60205260408120819055611ec284613936565b5f858152601160205260409020546002549192506001600160a01b0390811691611eef9183911685613a2a565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611f25908890879087908790600401615268565b5f604051808303815f87803b158015611f3c575f5ffd5b505af1158015611f4e573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611f8e929190918252602082015260400190565b60405180910390a25050505050565b611fbe60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166120138482613a55565b9250925050915091565b5f5f61202887610df5565b5f888152600d602052604090205490915060ff166003816006811115612050576120506147a4565b1488600383909192612078576040516337e1404160e01b8152600401610a8493929190615204565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156120dc576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156121135760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561213e57604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161215092919061529f565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506121929042614ea1565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906121df908d9085908c908c906004016152ae565b6020604051808303815f875af11580156121fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221f9190615124565b945088888661224357604051632f9f8ab960e01b8152600401610a849291906152cd565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516122779291906152cd565b60405180910390a2895f5160206158555f395f51905f52600360046040516122a092919061513f565b60405180910390a25050505095945050505050565b6122bd613827565b6127106122d2610120830161010084016152fa565b61ffff16111561231a5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b61271061232f610140830161012084016152fa565b61ffff1611156123765760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612388610140820161012083016152fa565b61ffff1615806123b157505f6123a5610100830160e08401614701565b6001600160a01b031614155b61240f5760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61242161018082016101608301615331565b63ffffffff1661243961016083016101408401615331565b63ffffffff1610156124975760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b8060186124a48282615370565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906154a8565b61254b6040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b5f5f6125f189610df5565b5f8a8152600d602052604090205490915060ff166004816006811115612619576126196147a4565b148a600483909192612641576040516337e1404160e01b8152600401610a8493929190615204565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156126a4576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f8b8152600860205260409020600d016126c18a8c8361556d565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161270592919061529f565b6040519081900381206001600160e01b031960e084901b168252612733918c908c908c908c90600401615621565b602060405180830381865afa15801561274e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127729190615124565b935089898561279657604051632f9f8ab960e01b8152600401610a849291906152cd565b50506127a18b613bdd565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516127d39291906152cd565b60405180910390a28a5f5160206158555f395f51905f52600460056040516127fc92919061513f565b60405180910390a2505050979650505050505050565b61281a613827565b80515f5b81811015612879576001600b84838151811061283c5761283c614e58565b6020026020010151604051612851919061515a565b908152604051908190036020019020805491151560ff1990921691909117905560010161281e565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611afb9190615170565b5f546001600160a01b03163314806128cb57506003546001600160a01b031633145b6129175760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff1611801561292d5750600d60ff821611155b6129725760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b612990828260ff16600d81111561298b5761298b6147a4565b614059565b5050565b61299c613827565b6001600160a01b0381166129f25760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a8c5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612ad6575f5ffd5b505af1158015612ae8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c8291815260200190565b612b26613827565b6001600160a01b03811615801590612b5757505f828152600960205260409020546001600160a01b03828116911614155b8290612b79576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611afb565b612bd9613827565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612c206020860186614e3f565b6003811115612c3157612c316147a4565b6003811115612c4257612c426147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c69579050505050505090505f81600160028110612cc057612cc0614e58565b602002015163ffffffff1611835f016020810190612cde9190614e3f565b90612cfd5760405163286c068d60e11b8152600401610a849190614e6c565b5060208181015182516040805161018081018252601854815260195494810194909452601a5490840152601b546060840152601c546080840152601d5460a0840152601e5460c0840152601f546001600160a01b03811660e085015261ffff600160a01b82048116610100860152600160b01b82041661012085015263ffffffff600160c01b820481166101408601819052600160e01b90920481166101608601529283169392909116919015612dfd5761014081015163ffffffff16846001602002015163ffffffff161015865f016020810190612ddc9190614e3f565b90612dfb5760405163010b971d60e31b8152600401610a849190614e6c565b505b61016081015163ffffffff1615612e4c5761016081015184519063ffffffff9081169082161015612e4a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610a84565b505b60408601356020870135811015612e795760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016546015545f929190612e9960208b013560408c0135614e8e565b612ea39190614ea1565b612ead9190614ea1565b612eb79190614ea1565b90505f612ec5600186614e8e565b612ed0906002615659565b612edb906002615659565b612ee6906006614ea1565b90505f85845f0151612ef89190615659565b905081868560200151612f0b9190615659565b612f159190615659565b612f1f9082614ea1565b90506001861115612f67576002612f37600188614e8e565b612f419088615659565b8560400151612f509190615659565b612f5a9190615670565b612f649082614ea1565b90505b81868560c00151612f789190615659565b612f829190615659565b612f8c9082614ea1565b905082868560600151612f9f9190615659565b612fa99190615659565b612fb39082614ea1565b9050848460800151612fc59190615659565b612fcf9082614ea1565b90506001851115613017576002612fe7600187614e8e565b612ff19087615659565b85604001516130009190615659565b61300a9190615670565b6130149082614ea1565b90505b60a08401516130269082614ea1565b610100850151909150612710906130419061ffff1682614ea1565b61304b9083615659565b6130559190615670565b9750878061307957604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b61308e613827565b6001600160a01b038116158015906130b457506001546001600160a01b03828116911614155b81906130d4576040516320252f0b60e01b8152600401610a849190614740565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac908390614740565b613128613827565b6131356020820182615331565b63ffffffff1661314b6040830160208401615331565b63ffffffff161015801561317057505f6131686020830183615331565b63ffffffff16115b6131b05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156132b95761014081015163ffffffff1661326a6040840160208501615331565b63ffffffff1610156132b95760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff161561332d5761016081015163ffffffff166132e36020840184615331565b63ffffffff16101561332d5760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f856003811115613343576133436147a4565b6003811115613354576133546147a4565b815260208101919091526040015f2061336e9160026143f1565b50826003811115613381576133816147a4565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516133b0919061568f565b60405180910390a2505050565b6133c5613827565b6001600160a01b0381166133ee575f604051631e4fbdf760e01b8152600401610a849190614740565b610bc8816138c6565b5f818152600d602052604081205460ff168181600681111561341b5761341b6147a4565b0361344057826001826040516337e1404160e01b8152600401610a8493929190615204565b6005816006811115613454576134546147a4565b036134755760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613489576134896147a4565b036134aa57604051633de16e3560e11b815260048101849052602401610a84565b5f6134b58483613a55565b93509050806134da57604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115613523576135236147a4565b0217905550835f5160206158555f395f51905f5283600660405161354892919061513f565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516135829291906156cf565b60405180910390a25050919050565b613599613827565b6001600160a01b038116158015906135be57505f546001600160a01b03828116911614155b81906135de576040516375ac4eb760e11b8152600401610a849190614740565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac908390614740565b6001600160a01b0381165f90815260076020526040902054819060ff16156136655760405163b29d459560e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac908390614740565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6136ea6141b4565b610bc8816141d9565b80356137365760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f8160200135116137825760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116137d15760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b33613830611d81565b6001600160a01b031614611a6d573360405163118cdaa760e01b8152600401610a849190614740565b6040516001600160a01b0384811660248301528381166044830152606482018390526138c09186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506141e1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d81111561395e5761395e6147a4565b148061397b5750600281600d811115613979576139796147a4565b145b156139b3575f5b6040519080825280602002602001820160405280156139ab578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613a1957506040513d5f823e601f3d908101601f19168201604052613a1691908101906156ea565b60015b613a23575f613982565b9392505050565b613a5083846001600160a01b031663a9059cbb858560405160240161388e929190615779565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613acf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613af39190614fb4565b90506001856006811115613b0957613b096147a4565b148015613b1557508042115b15613b2857600180935093505050613bd6565b6002856006811115613b3c57613b3c6147a4565b148015613b495750815142115b15613b5d5760016003935093505050613bd6565b6003856006811115613b7157613b716147a4565b148015613b815750816020015142115b15613b955760016006935093505050613bd6565b6004856006811115613ba957613ba96147a4565b148015613bb95750816040015142115b15613bcd576001600a935093505050613bd6565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613c22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c4991908101906156ea565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ce7576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613cb390889088908690600401615792565b5f604051808303815f87803b158015613cca575f5ffd5b505af1158015613cdc573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d2757506001600160a01b03811615155b15613d6357612710613d3d61ffff841687615659565b613d479190615670565b92508215613d6357613d636001600160a01b0385168285613a2a565b5f613d6e8487614e8e565b9050865f03613e22575f898152601060205260409020546001600160a01b03168015801590613d9c57505f82115b15613db557613db56001600160a01b0387168284613a2a565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613de9908d908d908b90600401615792565b5f604051808303815f87803b158015613e00575f5ffd5b505af1158015613e12573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115613e3b57613e3b6144f3565b604051908082528060200260200182016040528015613e64578160200160208202803683370190505b5090505f613e728984615670565b90505f805b8a811015613eb15782848281518110613e9257613e92614e58565b6020908102919091010152613ea78383614ea1565b9150600101613e77565b505f613ebd8286614e8e565b90508015613efa578084613ed260018e614e8e565b81518110613ee257613ee2614e58565b60200260200101818151613ef69190614ea1565b9052505b600154613f14906001600160a01b038b8116911687614244565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f58939291906157f2565b5f604051808303815f87803b158015613f6f575f5ffd5b505af1158015613f81573d5f5f3e3d5ffd5b5050600154613f9f92506001600160a01b038c81169250165f614244565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613fd1929190615827565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b815260040161401d93929190615792565b5f604051808303815f87803b158015614034575f5ffd5b505af1158015614046573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561407d5761407d6147a4565b036140a257826001826040516337e1404160e01b8152600401610a8493929190615204565b60058160068111156140b6576140b66147a4565b036140d75760405163462c7bed60e01b815260048101849052602401610a84565b60068160068111156140eb576140eb6147a4565b0361410c57604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d811115614155576141556147a4565b0217905550825f5160206158555f395f51905f5282600660405161417a92919061513f565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516133b09291906156cf565b6141bc6142d4565b611a6d57604051631afcd79f60e31b815260040160405180910390fd5b6133c56141b4565b5f5f60205f8451602086015f885af180614200576040513d5f823e3d81fd5b50505f513d91508115614217578060011415614224565b6001600160a01b0384163b155b156138c05783604051635274afe760e01b8152600401610a849190614740565b5f836001600160a01b031663095ea7b38484604051602401614267929190615779565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506142a084826142ed565b6138c0576142ca84856001600160a01b031663095ea7b3865f60405160240161388e929190615779565b6138c084826141e1565b5f6142dd6136b8565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561432c5750811561431e578060011461432c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161435e61448d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156143e1579160200282015b828111156143e15782518255916020019190600101906143c6565b506143ed9291506144ab565b5090565b6001830191839082156143e1579160200282015f5b8382111561445057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614406565b80156144805782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614450565b50506143ed9291506144ab565b60405180604001604052806002906020820280368337509192915050565b5b808211156143ed575f81556001016144ac565b6001600160a01b0381168114610bc8575f5ffd5b80356144de816144bf565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561452f5761452f6144f3565b604052919050565b5f6001600160401b0382111561454f5761454f6144f3565b5060051b60200190565b5f82601f830112614568575f5ffd5b81356001600160401b03811115614581576145816144f3565b614594601f8201601f1916602001614507565b8181528460208386010111156145a8575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126145d3575f5ffd5b81356145e66145e182614537565b614507565b8082825260208201915060208360051b860101925085831115614607575f5ffd5b602085015b838110156146475780356001600160401b03811115614629575f5ffd5b614638886020838a0101614559565b8452506020928301920161460c565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614669575f5ffd5b8835614674816144bf565b97506020890135614684816144bf565b96506040890135614694816144bf565b955060608901356146a4816144bf565b945060808901356146b4816144bf565b935060a089013592506146ca8a60c08b016144e3565b91506101208901356001600160401b038111156146e5575f5ffd5b6146f18b828c016145c4565b9150509295985092959890939650565b5f60208284031215614711575f5ffd5b8135613a23816144bf565b5f6020828403121561472c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106144de575f5ffd5b5f5f60408385031215614773575f5ffd5b61477c83614754565b946020939093013593505050565b5f6060828403121561479a575f5ffd5b613a2383836144e3565b634e487b7160e01b5f52602160045260245ffd5b600e81106147c8576147c86147a4565b9052565b602081016136dc82846147b8565b600481106147c8576147c86147a4565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614828602082018f6147da565b8c60408201528b6060820152614841608082018c614733565b6101c060a08201525f6148586101c083018c6147ea565b82810360c084015261486a818c6147ea565b905061487960e084018b614733565b61488761010084018a614733565b87610120840152866101408401528281036101608401526148a881876147ea565b9150506148b9610180830185614733565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156138c05781518452602093840193909101906001016148d8565b805182525f602082015161490e60208501826147da565b5060408201516040840152606082015161492b60608501826148d5565b50608082015160a084015260a082015161494860c0850182614733565b5060c082015161020060e08501526149646102008501826147ea565b905060e083015184820361010086015261497e82826147ea565b915050610100830151614995610120860182614733565b506101208301516149aa610140860182614733565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149dc82826147ea565b9150506101a08301516149f36101c0860182614733565b506101c08301518015156101e08601526139ab565b602081525f613a2360208301846148f7565b5f60208284031215614a2a575f5ffd5b81356001600160401b03811115614a3f575f5ffd5b614a4b84828501614559565b949350505050565b5f60208284031215614a63575f5ffd5b81356001600160401b03811115614a78575f5ffd5b82016101008185031215613a23575f5ffd5b828152604060208201525f614a4b60408301846148f7565b5f60208284031215614ab2575f5ffd5b81356001600160401b03811115614ac7575f5ffd5b614a4b848285016145c4565b5f5f60408385031215614ae4575f5ffd5b823591506020830135614af6816144bf565b809150509250929050565b5f5f60408385031215614b12575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016136dc565b821515815260408101613a2360208301846147b8565b5f5f83601f840112614b68575f5ffd5b5081356001600160401b03811115614b7e575f5ffd5b602083019150836020828501011115613bd6575f5ffd5b5f5f5f5f5f60608688031215614ba9575f5ffd5b8535945060208601356001600160401b03811115614bc5575f5ffd5b614bd188828901614b58565b90955093505060408601356001600160401b03811115614bef575f5ffd5b614bfb88828901614b58565b969995985093965092949392505050565b5f610180828403128015614c1e575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8060e0840182614733565b50610100830151614c9861010084018261ffff169052565b50610120830151614cb061012084018261ffff169052565b50610140830151614cca61014084018263ffffffff169052565b50610160830151614ce461016084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614d01575f5ffd5b8735965060208801356001600160401b03811115614d1d575f5ffd5b614d298a828b01614b58565b90975095505060408801356001600160401b03811115614d47575f5ffd5b614d538a828b01614b58565b90955093505060608801356001600160401b03811115614d71575f5ffd5b614d7d8a828b01614b58565b989b979a50959850939692959293505050565b5f5f60408385031215614da1575f5ffd5b82359150602083013560ff81168114614af6575f5ffd5b600781106147c8576147c86147a4565b602081016136dc8284614db8565b5f5f60608385031215614de7575f5ffd5b614df083614754565b915083606084011115614e01575f5ffd5b50926020919091019150565b600181811c90821680614e2157607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614e4f575f5ffd5b613a2382614754565b634e487b7160e01b5f52603260045260245ffd5b602081016136dc82846147da565b634e487b7160e01b5f52601160045260245ffd5b818103818111156136dc576136dc614e7a565b808201808211156136dc576136dc614e7a565b5f60018201614ec557614ec5614e7a565b5060010190565b5f5f8335601e19843603018112614ee1575f5ffd5b8301803591506001600160401b03821115614efa575f5ffd5b602001915036819003821315613bd6575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614f2b575f5ffd5b8135613a2381614f0e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614f7d60a08301888a614f36565b8281036060840152614f90818789614f36565b90508281036080840152614fa5818587614f36565b9b9a5050505050505050505050565b5f60208284031215614fc4575f5ffd5b5051919050565b601f821115613a5057805f5260205f20601f840160051c81016020851015614ff05750805b601f840160051c820191505b8181101561500f575f8155600101614ffc565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615043576150436144f3565b615057816150518454614e0d565b84614fcb565b6020601f821160018114615084575f83156150725750848201515b61507c8482615016565b85555061500f565b5f84815260208120601f198516915b828110156150b35787850151825560209485019460019092019101615093565b50848210156150d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561511957815163ffffffff168352602092830192909101906001016150f4565b505050949350505050565b5f60208284031215615134575f5ffd5b8151613a2381614f0e565b6040810161514d8285614db8565b613a236020830184614db8565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156151c757603f198786030184526151b28583516147ea565b94506020938401939190910190600101615196565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016152186020830185614db8565b614a4b6040830184614db8565b5f8151808452602084019350602083015f5b8281101561525e5781516001600160a01b0316865260209586019590910190600101615237565b5093949350505050565b848152836020820152608060408201525f6152866080830185615225565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61432c606083018486614f36565b602081525f614a4b602083018486614f36565b61ffff81168114610bc8575f5ffd5b80356144de816152e0565b5f6020828403121561530a575f5ffd5b8135613a23816152e0565b63ffffffff81168114610bc8575f5ffd5b80356144de81615315565b5f60208284031215615341575f5ffd5b8135613a2381615315565b5f81356136dc816144bf565b5f81356136dc816152e0565b5f81356136dc81615315565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016153e06153c360e0850161534c565b82546001600160a01b0319166001600160a01b0391909116178255565b6154106153f06101008501615358565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154406154206101208501615358565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154746154506101408501615364565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613a506154846101608501615364565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016154f960e084016144d3565b61550660e0840182614733565b5061551461010084016152ef565b61ffff1661010083015261552b61012084016152ef565b61ffff166101208301526155426101408401615326565b63ffffffff1661014083015261555b6101608401615326565b63ffffffff8116610160840152614ce4565b6001600160401b03831115615584576155846144f3565b615598836155928354614e0d565b83614fcb565b5f601f8411600181146155c4575f85156155b25750838201355b6155bc8682615016565b84555061500f565b5f83815260208120601f198716915b828110156155f357868501358255602094850194600190920191016155d3565b508682101561560f575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f61563a606083018688614f36565b828103604084015261564d818587614f36565b98975050505050505050565b80820281158282048414176136dc576136dc614e7a565b5f8261568a57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156156c65781356156ab81615315565b63ffffffff1683526020928301929190910190600101615697565b50505092915050565b604081016156dd8285614db8565b613a2360208301846147b8565b5f602082840312156156fa575f5ffd5b81516001600160401b0381111561570f575f5ffd5b8201601f8101841361571f575f5ffd5b805161572d6145e182614537565b8082825260208201915060208360051b85010192508683111561574e575f5ffd5b6020840193505b8284101561432c578351615768816144bf565b825260209384019390910190615755565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6157aa6060830185615225565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561525e5781518652602095860195909101906001016157d4565b6001600160a01b03841681526060602082018190525f9061581590830185615225565b828103604084015261432c81856157c2565b604081525f6158396040830185615225565b828103602084015261584b81856157c2565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610641578063ac3d2f4214610656578063b27392d51461067e578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a0d4664f1461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614651565b61081d565b005b6102f0610300366004614701565b610a2a565b61032d61031336600461471c565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614740565b60405180910390f35b61032d61035136600461471c565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614762565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a1366004614701565b610b12565b6102f06103b436600461478a565b610bb7565b6103db6103c736600461471c565b5f908152600f602052604090205460ff1690565b60405161033a91906147cc565b6103fb6103f636600461471c565b610bcb565b60405161033a9e9d9c9b9a99989796959493929190614818565b61042861042336600461471c565b610df5565b60405161033a9190614a08565b61045461044336600461471c565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614a1a565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae36600461471c565b6110f2565b6102f06104c1366004614701565b611181565b6104d96104d4366004614a53565b611214565b60405161033a929190614a8a565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a5c565b6102f0610519366004614aa2565b611a6f565b6102f061052c366004614ad3565b611b07565b6102f061053f36600461471c565b611b90565b6102f0610552366004614b01565b611c8e565b60015461032d906001600160a01b031681565b61032d611d81565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611daf565b60405161033a9190614b21565b6102f06105ba36600461471c565b611df5565b61059f6105cd36600461471c565b611f9d565b6105e56105e036600461471c565b611ff6565b60405161033a929190614b42565b61032d61060136600461471c565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614b95565b61201d565b6102f061063c366004614c0c565b6122b5565b6106496124d6565b60405161033a9190614c26565b61032d61066436600461471c565b5f908152600a60205260409020546001600160a01b031690565b61049061068c366004614ceb565b6125e6565b6102f061069f366004614aa2565b612812565b6102f06106b2366004614d90565b6128a9565b6102f06106c5366004614701565b612994565b6102f06106d8366004614b01565b612a3b565b6104906106eb366004614701565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610716366004614ad3565b612b1e565b6102f061072936600461471c565b612bd1565b61075061073c36600461471c565b5f908152600d602052604090205460ff1690565b60405161033a9190614dc8565b61045461076b366004614a53565b612c0e565b6102f061077e366004614701565b613086565b6102f0610791366004614dd6565b613120565b60025461032d906001600160a01b031681565b6102f06107b7366004614701565b6133bd565b6103db6107ca36600461471c565b6133f7565b6102f06107dd366004614701565b613591565b61032d6107f036600461471c565b600a6020525f90815260409020546001600160a01b031681565b6102f0610818366004614701565b613629565b5f6108266136b8565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336136e2565b6108cf88612bd1565b6108d88c613591565b6108e18b613086565b6108ea8a610a2a565b6108f389610b12565b6108fc876136f3565b61090586612812565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601894909455601992909255601a94909455601b93909355601c92909255601d91909155601e55607d60a31b601f556109b4611d81565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6133bd565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613827565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613827565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a849190614740565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac908390614740565b60405180910390a150565b610bbf613827565b610bc8816136f3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614e0d565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614e0d565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614e0d565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614336565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a6147a4565b6003811115610e4b57610e4b6147a4565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614e0d565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614e0d565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614e0d565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613827565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613827565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac908390614740565b5f61121d614336565b5f60128161122e6020870187614e3f565b600381111561123f5761123f6147a4565b6003811115611250576112506147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614e58565b602002015163ffffffff1611845f0160208101906112ec9190614e3f565b9061130b5760405163286c068d60e11b8152600401610a849190614e6c565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016545f919061137b426040890135614e8e565b6113859190614ea1565b61138f9190614ea1565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc6080880160608901614701565b6001600160a01b0316815260208101919091526040015f205460ff166113f86080870160608801614701565b906114175760405163295a6a6f60e11b8152600401610a849190614740565b505f61142286612c0e565b60068054965090915085905f61143783614eb4565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506115129190890135614ea1565b5f878152600e602090815260409091206001019190915581865261153890880188614e3f565b8560200190600381111561154e5761154e6147a4565b90816003811115611561576115616147a4565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526115a99060808901908901614701565b6001600160a01b031660a08601526115c46080880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261160c90880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611659906101008901908901614f1b565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a086018190526004546116a9916001600160a01b03909116903085613859565b5f6116ba6080890160608a01614701565b6001600160a01b031663fefd9a8b88846116d760808d018d614ecc565b6116e460a08f018f614ecc565b8f8060c001906116f49190614ecc565b6040518963ffffffff1660e01b8152600401611717989796959493929190614f5e565b6020604051808303815f875af1158015611733573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117579190614fb4565b5f818152600960205260409020549091506001600160a01b03168181611793576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b031682816117cd576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561182b5761182b6147a4565b0217905550604082015181600201556060820151816003019060026118519291906143b3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611896908261502a565b5060e082015160088201906118ab908261502a565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611913908261502a565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611979908c9088908c906004016150df565b6020604051808303815f875af1158015611995573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b99190615124565b6119d657604051630d8dbe2560e01b815260040160405180910390fd5b6119e660808b0160608c01614701565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611a20929190614a8a565b60405180910390a2885f5160206158555f395f51905f525f6001604051611a4892919061513f565b60405180910390a250505050505050915091565b611a64613827565b611a6d5f6138c6565b565b611a77613827565b80515f5b81811015611acb57600b838281518110611a9757611a97614e58565b6020026020010151604051611aac919061515a565b908152604051908190036020019020805460ff19169055600101611a7b565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611afb9190615170565b60405180910390a15050565b611b0f613827565b6001600160a01b03811615801590611b4057505f828152600a60205260409020546001600160a01b03828116911614155b8290611b62576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611bb95760405162461bcd60e51b8152600401610a84906151d3565b5f818152600d602052604090205460ff166001816006811115611bde57611bde6147a4565b14611c0357816001826040516337e1404160e01b8152600401610a8493929190615204565b5f828152600d60205260409020805460ff19166002179055601554611c289042614ea1565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206158555f395f51905f5260016002604051611c8292919061513f565b60405180910390a25050565b5f546001600160a01b03163314611cb75760405162461bcd60e51b8152600401610a84906151d3565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ce757611ce76147a4565b14611d0c57836002826040516337e1404160e01b8152600401610a8493929190615204565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206158555f395f51905f5260026003604051611d7392919061513f565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611dd060405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611e1a57611e1a6147a4565b14611e575760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c602052604090205480611ea95760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c60205260408120819055611ec284613936565b5f858152601160205260409020546002549192506001600160a01b0390811691611eef9183911685613a2a565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611f25908890879087908790600401615268565b5f604051808303815f87803b158015611f3c575f5ffd5b505af1158015611f4e573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611f8e929190918252602082015260400190565b60405180910390a25050505050565b611fbe60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166120138482613a55565b9250925050915091565b5f5f61202887610df5565b5f888152600d602052604090205490915060ff166003816006811115612050576120506147a4565b1488600383909192612078576040516337e1404160e01b8152600401610a8493929190615204565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156120dc576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156121135760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561213e57604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161215092919061529f565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506121929042614ea1565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906121df908d9085908c908c906004016152ae565b6020604051808303815f875af11580156121fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221f9190615124565b945088888661224357604051632f9f8ab960e01b8152600401610a849291906152cd565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516122779291906152cd565b60405180910390a2895f5160206158555f395f51905f52600360046040516122a092919061513f565b60405180910390a25050505095945050505050565b6122bd613827565b6127106122d2610120830161010084016152fa565b61ffff16111561231a5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b61271061232f610140830161012084016152fa565b61ffff1611156123765760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612388610140820161012083016152fa565b61ffff1615806123b157505f6123a5610100830160e08401614701565b6001600160a01b031614155b61240f5760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61242161018082016101608301615331565b63ffffffff1661243961016083016101408401615331565b63ffffffff1610156124975760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b8060186124a48282615370565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906154a8565b61254b6040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b5f5f6125f189610df5565b5f8a8152600d602052604090205490915060ff166004816006811115612619576126196147a4565b148a600483909192612641576040516337e1404160e01b8152600401610a8493929190615204565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156126a4576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f8b8152600860205260409020600d016126c18a8c8361556d565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161270592919061529f565b6040519081900381206001600160e01b031960e084901b168252612733918c908c908c908c90600401615621565b602060405180830381865afa15801561274e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127729190615124565b935089898561279657604051632f9f8ab960e01b8152600401610a849291906152cd565b50506127a18b613bdd565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516127d39291906152cd565b60405180910390a28a5f5160206158555f395f51905f52600460056040516127fc92919061513f565b60405180910390a2505050979650505050505050565b61281a613827565b80515f5b81811015612879576001600b84838151811061283c5761283c614e58565b6020026020010151604051612851919061515a565b908152604051908190036020019020805491151560ff1990921691909117905560010161281e565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611afb9190615170565b5f546001600160a01b03163314806128cb57506003546001600160a01b031633145b6129175760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff1611801561292d5750600d60ff821611155b6129725760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b612990828260ff16600d81111561298b5761298b6147a4565b614059565b5050565b61299c613827565b6001600160a01b0381166129f25760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a8c5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612ad6575f5ffd5b505af1158015612ae8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c8291815260200190565b612b26613827565b6001600160a01b03811615801590612b5757505f828152600960205260409020546001600160a01b03828116911614155b8290612b79576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611afb565b612bd9613827565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612c206020860186614e3f565b6003811115612c3157612c316147a4565b6003811115612c4257612c426147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c69579050505050505090505f81600160028110612cc057612cc0614e58565b602002015163ffffffff1611835f016020810190612cde9190614e3f565b90612cfd5760405163286c068d60e11b8152600401610a849190614e6c565b5060208181015182516040805161018081018252601854815260195494810194909452601a5490840152601b546060840152601c546080840152601d5460a0840152601e5460c0840152601f546001600160a01b03811660e085015261ffff600160a01b82048116610100860152600160b01b82041661012085015263ffffffff600160c01b820481166101408601819052600160e01b90920481166101608601529283169392909116919015612dfd5761014081015163ffffffff16846001602002015163ffffffff161015865f016020810190612ddc9190614e3f565b90612dfb5760405163010b971d60e31b8152600401610a849190614e6c565b505b61016081015163ffffffff1615612e4c5761016081015184519063ffffffff9081169082161015612e4a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610a84565b505b60408601356020870135811015612e795760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016546015545f929190612e9960208b013560408c0135614e8e565b612ea39190614ea1565b612ead9190614ea1565b612eb79190614ea1565b90505f612ec5600186614e8e565b612ed0906002615659565b612edb906002615659565b612ee6906006614ea1565b90505f85845f0151612ef89190615659565b905081868560200151612f0b9190615659565b612f159190615659565b612f1f9082614ea1565b90506001861115612f67576002612f37600188614e8e565b612f419088615659565b8560400151612f509190615659565b612f5a9190615670565b612f649082614ea1565b90505b81868560c00151612f789190615659565b612f829190615659565b612f8c9082614ea1565b905082868560600151612f9f9190615659565b612fa99190615659565b612fb39082614ea1565b9050848460800151612fc59190615659565b612fcf9082614ea1565b90506001851115613017576002612fe7600187614e8e565b612ff19087615659565b85604001516130009190615659565b61300a9190615670565b6130149082614ea1565b90505b60a08401516130269082614ea1565b610100850151909150612710906130419061ffff1682614ea1565b61304b9083615659565b6130559190615670565b9750878061307957604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b61308e613827565b6001600160a01b038116158015906130b457506001546001600160a01b03828116911614155b81906130d4576040516320252f0b60e01b8152600401610a849190614740565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac908390614740565b613128613827565b6131356020820182615331565b63ffffffff1661314b6040830160208401615331565b63ffffffff161015801561317057505f6131686020830183615331565b63ffffffff16115b6131b05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156132b95761014081015163ffffffff1661326a6040840160208501615331565b63ffffffff1610156132b95760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff161561332d5761016081015163ffffffff166132e36020840184615331565b63ffffffff16101561332d5760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f856003811115613343576133436147a4565b6003811115613354576133546147a4565b815260208101919091526040015f2061336e9160026143f1565b50826003811115613381576133816147a4565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516133b0919061568f565b60405180910390a2505050565b6133c5613827565b6001600160a01b0381166133ee575f604051631e4fbdf760e01b8152600401610a849190614740565b610bc8816138c6565b5f818152600d602052604081205460ff168181600681111561341b5761341b6147a4565b0361344057826001826040516337e1404160e01b8152600401610a8493929190615204565b6005816006811115613454576134546147a4565b036134755760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613489576134896147a4565b036134aa57604051633de16e3560e11b815260048101849052602401610a84565b5f6134b58483613a55565b93509050806134da57604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115613523576135236147a4565b0217905550835f5160206158555f395f51905f5283600660405161354892919061513f565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516135829291906156cf565b60405180910390a25050919050565b613599613827565b6001600160a01b038116158015906135be57505f546001600160a01b03828116911614155b81906135de576040516375ac4eb760e11b8152600401610a849190614740565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac908390614740565b6001600160a01b0381165f90815260076020526040902054819060ff16156136655760405163b29d459560e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac908390614740565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6136ea6141b4565b610bc8816141d9565b80356137365760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f8160200135116137825760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116137d15760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b33613830611d81565b6001600160a01b031614611a6d573360405163118cdaa760e01b8152600401610a849190614740565b6040516001600160a01b0384811660248301528381166044830152606482018390526138c09186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506141e1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d81111561395e5761395e6147a4565b148061397b5750600281600d811115613979576139796147a4565b145b156139b3575f5b6040519080825280602002602001820160405280156139ab578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613a1957506040513d5f823e601f3d908101601f19168201604052613a1691908101906156ea565b60015b613a23575f613982565b9392505050565b613a5083846001600160a01b031663a9059cbb858560405160240161388e929190615779565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613acf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613af39190614fb4565b90506001856006811115613b0957613b096147a4565b148015613b1557508042115b15613b2857600180935093505050613bd6565b6002856006811115613b3c57613b3c6147a4565b148015613b495750815142115b15613b5d5760016003935093505050613bd6565b6003856006811115613b7157613b716147a4565b148015613b815750816020015142115b15613b955760016006935093505050613bd6565b6004856006811115613ba957613ba96147a4565b148015613bb95750816040015142115b15613bcd576001600a935093505050613bd6565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613c22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c4991908101906156ea565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ce7576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613cb390889088908690600401615792565b5f604051808303815f87803b158015613cca575f5ffd5b505af1158015613cdc573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d2757506001600160a01b03811615155b15613d6357612710613d3d61ffff841687615659565b613d479190615670565b92508215613d6357613d636001600160a01b0385168285613a2a565b5f613d6e8487614e8e565b9050865f03613e22575f898152601060205260409020546001600160a01b03168015801590613d9c57505f82115b15613db557613db56001600160a01b0387168284613a2a565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613de9908d908d908b90600401615792565b5f604051808303815f87803b158015613e00575f5ffd5b505af1158015613e12573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115613e3b57613e3b6144f3565b604051908082528060200260200182016040528015613e64578160200160208202803683370190505b5090505f613e728984615670565b90505f805b8a811015613eb15782848281518110613e9257613e92614e58565b6020908102919091010152613ea78383614ea1565b9150600101613e77565b505f613ebd8286614e8e565b90508015613efa578084613ed260018e614e8e565b81518110613ee257613ee2614e58565b60200260200101818151613ef69190614ea1565b9052505b600154613f14906001600160a01b038b8116911687614244565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f58939291906157f2565b5f604051808303815f87803b158015613f6f575f5ffd5b505af1158015613f81573d5f5f3e3d5ffd5b5050600154613f9f92506001600160a01b038c81169250165f614244565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613fd1929190615827565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b815260040161401d93929190615792565b5f604051808303815f87803b158015614034575f5ffd5b505af1158015614046573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561407d5761407d6147a4565b036140a257826001826040516337e1404160e01b8152600401610a8493929190615204565b60058160068111156140b6576140b66147a4565b036140d75760405163462c7bed60e01b815260048101849052602401610a84565b60068160068111156140eb576140eb6147a4565b0361410c57604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d811115614155576141556147a4565b0217905550825f5160206158555f395f51905f5282600660405161417a92919061513f565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516133b09291906156cf565b6141bc6142d4565b611a6d57604051631afcd79f60e31b815260040160405180910390fd5b6133c56141b4565b5f5f60205f8451602086015f885af180614200576040513d5f823e3d81fd5b50505f513d91508115614217578060011415614224565b6001600160a01b0384163b155b156138c05783604051635274afe760e01b8152600401610a849190614740565b5f836001600160a01b031663095ea7b38484604051602401614267929190615779565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506142a084826142ed565b6138c0576142ca84856001600160a01b031663095ea7b3865f60405160240161388e929190615779565b6138c084826141e1565b5f6142dd6136b8565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561432c5750811561431e578060011461432c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161435e61448d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156143e1579160200282015b828111156143e15782518255916020019190600101906143c6565b506143ed9291506144ab565b5090565b6001830191839082156143e1579160200282015f5b8382111561445057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614406565b80156144805782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614450565b50506143ed9291506144ab565b60405180604001604052806002906020820280368337509192915050565b5b808211156143ed575f81556001016144ac565b6001600160a01b0381168114610bc8575f5ffd5b80356144de816144bf565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561452f5761452f6144f3565b604052919050565b5f6001600160401b0382111561454f5761454f6144f3565b5060051b60200190565b5f82601f830112614568575f5ffd5b81356001600160401b03811115614581576145816144f3565b614594601f8201601f1916602001614507565b8181528460208386010111156145a8575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126145d3575f5ffd5b81356145e66145e182614537565b614507565b8082825260208201915060208360051b860101925085831115614607575f5ffd5b602085015b838110156146475780356001600160401b03811115614629575f5ffd5b614638886020838a0101614559565b8452506020928301920161460c565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614669575f5ffd5b8835614674816144bf565b97506020890135614684816144bf565b96506040890135614694816144bf565b955060608901356146a4816144bf565b945060808901356146b4816144bf565b935060a089013592506146ca8a60c08b016144e3565b91506101208901356001600160401b038111156146e5575f5ffd5b6146f18b828c016145c4565b9150509295985092959890939650565b5f60208284031215614711575f5ffd5b8135613a23816144bf565b5f6020828403121561472c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106144de575f5ffd5b5f5f60408385031215614773575f5ffd5b61477c83614754565b946020939093013593505050565b5f6060828403121561479a575f5ffd5b613a2383836144e3565b634e487b7160e01b5f52602160045260245ffd5b600e81106147c8576147c86147a4565b9052565b602081016136dc82846147b8565b600481106147c8576147c86147a4565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614828602082018f6147da565b8c60408201528b6060820152614841608082018c614733565b6101c060a08201525f6148586101c083018c6147ea565b82810360c084015261486a818c6147ea565b905061487960e084018b614733565b61488761010084018a614733565b87610120840152866101408401528281036101608401526148a881876147ea565b9150506148b9610180830185614733565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156138c05781518452602093840193909101906001016148d8565b805182525f602082015161490e60208501826147da565b5060408201516040840152606082015161492b60608501826148d5565b50608082015160a084015260a082015161494860c0850182614733565b5060c082015161020060e08501526149646102008501826147ea565b905060e083015184820361010086015261497e82826147ea565b915050610100830151614995610120860182614733565b506101208301516149aa610140860182614733565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149dc82826147ea565b9150506101a08301516149f36101c0860182614733565b506101c08301518015156101e08601526139ab565b602081525f613a2360208301846148f7565b5f60208284031215614a2a575f5ffd5b81356001600160401b03811115614a3f575f5ffd5b614a4b84828501614559565b949350505050565b5f60208284031215614a63575f5ffd5b81356001600160401b03811115614a78575f5ffd5b82016101008185031215613a23575f5ffd5b828152604060208201525f614a4b60408301846148f7565b5f60208284031215614ab2575f5ffd5b81356001600160401b03811115614ac7575f5ffd5b614a4b848285016145c4565b5f5f60408385031215614ae4575f5ffd5b823591506020830135614af6816144bf565b809150509250929050565b5f5f60408385031215614b12575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016136dc565b821515815260408101613a2360208301846147b8565b5f5f83601f840112614b68575f5ffd5b5081356001600160401b03811115614b7e575f5ffd5b602083019150836020828501011115613bd6575f5ffd5b5f5f5f5f5f60608688031215614ba9575f5ffd5b8535945060208601356001600160401b03811115614bc5575f5ffd5b614bd188828901614b58565b90955093505060408601356001600160401b03811115614bef575f5ffd5b614bfb88828901614b58565b969995985093965092949392505050565b5f610180828403128015614c1e575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8060e0840182614733565b50610100830151614c9861010084018261ffff169052565b50610120830151614cb061012084018261ffff169052565b50610140830151614cca61014084018263ffffffff169052565b50610160830151614ce461016084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614d01575f5ffd5b8735965060208801356001600160401b03811115614d1d575f5ffd5b614d298a828b01614b58565b90975095505060408801356001600160401b03811115614d47575f5ffd5b614d538a828b01614b58565b90955093505060608801356001600160401b03811115614d71575f5ffd5b614d7d8a828b01614b58565b989b979a50959850939692959293505050565b5f5f60408385031215614da1575f5ffd5b82359150602083013560ff81168114614af6575f5ffd5b600781106147c8576147c86147a4565b602081016136dc8284614db8565b5f5f60608385031215614de7575f5ffd5b614df083614754565b915083606084011115614e01575f5ffd5b50926020919091019150565b600181811c90821680614e2157607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614e4f575f5ffd5b613a2382614754565b634e487b7160e01b5f52603260045260245ffd5b602081016136dc82846147da565b634e487b7160e01b5f52601160045260245ffd5b818103818111156136dc576136dc614e7a565b808201808211156136dc576136dc614e7a565b5f60018201614ec557614ec5614e7a565b5060010190565b5f5f8335601e19843603018112614ee1575f5ffd5b8301803591506001600160401b03821115614efa575f5ffd5b602001915036819003821315613bd6575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614f2b575f5ffd5b8135613a2381614f0e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614f7d60a08301888a614f36565b8281036060840152614f90818789614f36565b90508281036080840152614fa5818587614f36565b9b9a5050505050505050505050565b5f60208284031215614fc4575f5ffd5b5051919050565b601f821115613a5057805f5260205f20601f840160051c81016020851015614ff05750805b601f840160051c820191505b8181101561500f575f8155600101614ffc565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615043576150436144f3565b615057816150518454614e0d565b84614fcb565b6020601f821160018114615084575f83156150725750848201515b61507c8482615016565b85555061500f565b5f84815260208120601f198516915b828110156150b35787850151825560209485019460019092019101615093565b50848210156150d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561511957815163ffffffff168352602092830192909101906001016150f4565b505050949350505050565b5f60208284031215615134575f5ffd5b8151613a2381614f0e565b6040810161514d8285614db8565b613a236020830184614db8565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156151c757603f198786030184526151b28583516147ea565b94506020938401939190910190600101615196565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016152186020830185614db8565b614a4b6040830184614db8565b5f8151808452602084019350602083015f5b8281101561525e5781516001600160a01b0316865260209586019590910190600101615237565b5093949350505050565b848152836020820152608060408201525f6152866080830185615225565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61432c606083018486614f36565b602081525f614a4b602083018486614f36565b61ffff81168114610bc8575f5ffd5b80356144de816152e0565b5f6020828403121561530a575f5ffd5b8135613a23816152e0565b63ffffffff81168114610bc8575f5ffd5b80356144de81615315565b5f60208284031215615341575f5ffd5b8135613a2381615315565b5f81356136dc816144bf565b5f81356136dc816152e0565b5f81356136dc81615315565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016153e06153c360e0850161534c565b82546001600160a01b0319166001600160a01b0391909116178255565b6154106153f06101008501615358565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154406154206101208501615358565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154746154506101408501615364565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613a506154846101608501615364565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016154f960e084016144d3565b61550660e0840182614733565b5061551461010084016152ef565b61ffff1661010083015261552b61012084016152ef565b61ffff166101208301526155426101408401615326565b63ffffffff1661014083015261555b6101608401615326565b63ffffffff8116610160840152614ce4565b6001600160401b03831115615584576155846144f3565b615598836155928354614e0d565b83614fcb565b5f601f8411600181146155c4575f85156155b25750838201355b6155bc8682615016565b84555061500f565b5f83815260208120601f198716915b828110156155f357868501358255602094850194600190920191016155d3565b508682101561560f575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f61563a606083018688614f36565b828103604084015261564d818587614f36565b98975050505050505050565b80820281158282048414176136dc576136dc614e7a565b5f8261568a57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156156c65781356156ab81615315565b63ffffffff1683526020928301929190910190600101615697565b50505092915050565b604081016156dd8285614db8565b613a2360208301846147b8565b5f602082840312156156fa575f5ffd5b81516001600160401b0381111561570f575f5ffd5b8201601f8101841361571f575f5ffd5b805161572d6145e182614537565b8082825260208201915060208360051b85010192508683111561574e575f5ffd5b6020840193505b8284101561432c578351615768816144bf565b825260209384019390910190615755565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6157aa6060830185615225565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561525e5781518652602095860195909101906001016157d4565b6001600160a01b03841681526060602082018190525f9061581590830185615225565b828103604084015261432c81856157c2565b604081525f6158396040830185615225565b828103602084015261584b81856157c2565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 02e4b61f84..01a3a8bfc5 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index b007af4921..524824e24a 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -787,5 +787,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index d72e4676ab..ce9ffde947 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -1620,5 +1620,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index b54e18c412..4360695441 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index 46037563f5..3d0e5cd184 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1303,5 +1303,5 @@ }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-37fb927866c741fdeff7bc0d84b6ce759b2dcddc" + "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" } \ No newline at end of file diff --git a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts index 887b43ad69..81ab713416 100644 --- a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts +++ b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts @@ -165,9 +165,8 @@ describe("BfvDecryptionVerifier", function () { }); it("returns false when fold proof is present but fold verifier returns false", async function () { - const { bfvDecryptionVerifier, mockCircuit, mockFold } = await loadFixture( - deployWithMockCircuit, - ); + const { bfvDecryptionVerifier, mockCircuit, mockFold } = + await loadFixture(deployWithMockCircuit); await mockCircuit.setReturnValue(true); await mockFold.setReturnValue(false); @@ -230,9 +229,8 @@ describe("BfvDecryptionVerifier", function () { }); it("returns true when fold proof is present and fold verifies", async function () { - const { bfvDecryptionVerifier, mockCircuit, mockFold } = await loadFixture( - deployWithMockCircuit, - ); + const { bfvDecryptionVerifier, mockCircuit, mockFold } = + await loadFixture(deployWithMockCircuit); await mockCircuit.setReturnValue(true); await mockFold.setReturnValue(true); diff --git a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts index 26d37e8b9d..b1faa93a65 100644 --- a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -491,7 +491,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await expect(registry.publishCommittee(0, nodes, publicKey, pkProof, "0x")) + await expect( + registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"), + ) .to.emit(enclave, "CommitteeFormed") .withArgs(0); }); @@ -1484,7 +1486,12 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ); const plaintextOutput = "0x" + "cd".repeat(100); - await enclave.publishPlaintextOutput(0, plaintextOutput, proofBytes, "0x"); + await enclave.publishPlaintextOutput( + 0, + plaintextOutput, + proofBytes, + "0x", + ); expect(await enclave.getE3Stage(0)).to.equal(5); // Complete // 4. Verify escrowed slashed funds were distributed diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index ebb99e0df5..554d68cda4 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -643,7 +643,7 @@ describe("E3 Pricing", function () { const op3Before = await usdcToken.balanceOf(nodes[2]); // Publish plaintext (triggers _distributeRewards) - await enclave.publishPlaintextOutput(e3Id, data, proof); + await enclave.publishPlaintextOutput(e3Id, data, proof, proof); const op1After = await usdcToken.balanceOf(nodes[0]); const op2After = await usdcToken.balanceOf(nodes[1]); @@ -725,7 +725,7 @@ describe("E3 Pricing", function () { const op2Before = await usdcToken.balanceOf(nodes[1]); const op3Before = await usdcToken.balanceOf(nodes[2]); - await enclave.publishPlaintextOutput(e3Id, data, proof); + await enclave.publishPlaintextOutput(e3Id, data, proof, proof); const treasuryAfter = await usdcToken.balanceOf(treasuryAddr); const op1After = await usdcToken.balanceOf(nodes[0]); From f5479c0643dc19dd6d504ca4b13ab76c5b53bd79 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Thu, 26 Mar 2026 00:11:39 +0500 Subject: [PATCH 10/11] fix: resolve conflicts --- .../contracts/Enclave.sol/Enclave.json | 51 +++++++++++++++++-- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 15 +++++- .../interfaces/IEnclave.sol/IEnclave.json | 47 ++++++++++++++++- .../ISlashingManager.json | 2 +- .../CiphernodeRegistryOwnable.json | 2 +- .../enclave-contracts/contracts/Enclave.sol | 32 ++++++++++-- .../interfaces/ICiphernodeRegistry.sol | 4 ++ .../contracts/interfaces/IEnclave.sol | 3 ++ .../contracts/test/MockCiphernodeRegistry.sol | 8 +++ .../scripts/deployEnclave.ts | 3 ++ .../test/Pricing/Pricing.spec.ts | 29 ++++++++--- 12 files changed, 177 insertions(+), 21 deletions(-) diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index b9f3c5f362..b1a6ff8a9f 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -889,6 +889,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -1633,6 +1648,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -2312,6 +2342,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -2403,11 +2448,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615881806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610641578063ac3d2f4214610656578063b27392d51461067e578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a0d4664f1461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614651565b61081d565b005b6102f0610300366004614701565b610a2a565b61032d61031336600461471c565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614740565b60405180910390f35b61032d61035136600461471c565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614762565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a1366004614701565b610b12565b6102f06103b436600461478a565b610bb7565b6103db6103c736600461471c565b5f908152600f602052604090205460ff1690565b60405161033a91906147cc565b6103fb6103f636600461471c565b610bcb565b60405161033a9e9d9c9b9a99989796959493929190614818565b61042861042336600461471c565b610df5565b60405161033a9190614a08565b61045461044336600461471c565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614a1a565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae36600461471c565b6110f2565b6102f06104c1366004614701565b611181565b6104d96104d4366004614a53565b611214565b60405161033a929190614a8a565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a5c565b6102f0610519366004614aa2565b611a6f565b6102f061052c366004614ad3565b611b07565b6102f061053f36600461471c565b611b90565b6102f0610552366004614b01565b611c8e565b60015461032d906001600160a01b031681565b61032d611d81565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611daf565b60405161033a9190614b21565b6102f06105ba36600461471c565b611df5565b61059f6105cd36600461471c565b611f9d565b6105e56105e036600461471c565b611ff6565b60405161033a929190614b42565b61032d61060136600461471c565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614b95565b61201d565b6102f061063c366004614c0c565b6122b5565b6106496124d6565b60405161033a9190614c26565b61032d61066436600461471c565b5f908152600a60205260409020546001600160a01b031690565b61049061068c366004614ceb565b6125e6565b6102f061069f366004614aa2565b612812565b6102f06106b2366004614d90565b6128a9565b6102f06106c5366004614701565b612994565b6102f06106d8366004614b01565b612a3b565b6104906106eb366004614701565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610716366004614ad3565b612b1e565b6102f061072936600461471c565b612bd1565b61075061073c36600461471c565b5f908152600d602052604090205460ff1690565b60405161033a9190614dc8565b61045461076b366004614a53565b612c0e565b6102f061077e366004614701565b613086565b6102f0610791366004614dd6565b613120565b60025461032d906001600160a01b031681565b6102f06107b7366004614701565b6133bd565b6103db6107ca36600461471c565b6133f7565b6102f06107dd366004614701565b613591565b61032d6107f036600461471c565b600a6020525f90815260409020546001600160a01b031681565b6102f0610818366004614701565b613629565b5f6108266136b8565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336136e2565b6108cf88612bd1565b6108d88c613591565b6108e18b613086565b6108ea8a610a2a565b6108f389610b12565b6108fc876136f3565b61090586612812565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601894909455601992909255601a94909455601b93909355601c92909255601d91909155601e55607d60a31b601f556109b4611d81565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6133bd565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613827565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613827565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a849190614740565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac908390614740565b60405180910390a150565b610bbf613827565b610bc8816136f3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614e0d565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614e0d565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614e0d565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614336565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a6147a4565b6003811115610e4b57610e4b6147a4565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614e0d565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614e0d565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614e0d565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613827565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613827565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac908390614740565b5f61121d614336565b5f60128161122e6020870187614e3f565b600381111561123f5761123f6147a4565b6003811115611250576112506147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614e58565b602002015163ffffffff1611845f0160208101906112ec9190614e3f565b9061130b5760405163286c068d60e11b8152600401610a849190614e6c565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016545f919061137b426040890135614e8e565b6113859190614ea1565b61138f9190614ea1565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc6080880160608901614701565b6001600160a01b0316815260208101919091526040015f205460ff166113f86080870160608801614701565b906114175760405163295a6a6f60e11b8152600401610a849190614740565b505f61142286612c0e565b60068054965090915085905f61143783614eb4565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506115129190890135614ea1565b5f878152600e602090815260409091206001019190915581865261153890880188614e3f565b8560200190600381111561154e5761154e6147a4565b90816003811115611561576115616147a4565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526115a99060808901908901614701565b6001600160a01b031660a08601526115c46080880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261160c90880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611659906101008901908901614f1b565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a086018190526004546116a9916001600160a01b03909116903085613859565b5f6116ba6080890160608a01614701565b6001600160a01b031663fefd9a8b88846116d760808d018d614ecc565b6116e460a08f018f614ecc565b8f8060c001906116f49190614ecc565b6040518963ffffffff1660e01b8152600401611717989796959493929190614f5e565b6020604051808303815f875af1158015611733573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117579190614fb4565b5f818152600960205260409020549091506001600160a01b03168181611793576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b031682816117cd576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561182b5761182b6147a4565b0217905550604082015181600201556060820151816003019060026118519291906143b3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611896908261502a565b5060e082015160088201906118ab908261502a565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611913908261502a565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611979908c9088908c906004016150df565b6020604051808303815f875af1158015611995573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b99190615124565b6119d657604051630d8dbe2560e01b815260040160405180910390fd5b6119e660808b0160608c01614701565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611a20929190614a8a565b60405180910390a2885f5160206158555f395f51905f525f6001604051611a4892919061513f565b60405180910390a250505050505050915091565b611a64613827565b611a6d5f6138c6565b565b611a77613827565b80515f5b81811015611acb57600b838281518110611a9757611a97614e58565b6020026020010151604051611aac919061515a565b908152604051908190036020019020805460ff19169055600101611a7b565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611afb9190615170565b60405180910390a15050565b611b0f613827565b6001600160a01b03811615801590611b4057505f828152600a60205260409020546001600160a01b03828116911614155b8290611b62576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611bb95760405162461bcd60e51b8152600401610a84906151d3565b5f818152600d602052604090205460ff166001816006811115611bde57611bde6147a4565b14611c0357816001826040516337e1404160e01b8152600401610a8493929190615204565b5f828152600d60205260409020805460ff19166002179055601554611c289042614ea1565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206158555f395f51905f5260016002604051611c8292919061513f565b60405180910390a25050565b5f546001600160a01b03163314611cb75760405162461bcd60e51b8152600401610a84906151d3565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ce757611ce76147a4565b14611d0c57836002826040516337e1404160e01b8152600401610a8493929190615204565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206158555f395f51905f5260026003604051611d7392919061513f565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611dd060405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611e1a57611e1a6147a4565b14611e575760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c602052604090205480611ea95760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c60205260408120819055611ec284613936565b5f858152601160205260409020546002549192506001600160a01b0390811691611eef9183911685613a2a565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611f25908890879087908790600401615268565b5f604051808303815f87803b158015611f3c575f5ffd5b505af1158015611f4e573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611f8e929190918252602082015260400190565b60405180910390a25050505050565b611fbe60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166120138482613a55565b9250925050915091565b5f5f61202887610df5565b5f888152600d602052604090205490915060ff166003816006811115612050576120506147a4565b1488600383909192612078576040516337e1404160e01b8152600401610a8493929190615204565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156120dc576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156121135760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561213e57604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161215092919061529f565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506121929042614ea1565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906121df908d9085908c908c906004016152ae565b6020604051808303815f875af11580156121fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221f9190615124565b945088888661224357604051632f9f8ab960e01b8152600401610a849291906152cd565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516122779291906152cd565b60405180910390a2895f5160206158555f395f51905f52600360046040516122a092919061513f565b60405180910390a25050505095945050505050565b6122bd613827565b6127106122d2610120830161010084016152fa565b61ffff16111561231a5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b61271061232f610140830161012084016152fa565b61ffff1611156123765760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612388610140820161012083016152fa565b61ffff1615806123b157505f6123a5610100830160e08401614701565b6001600160a01b031614155b61240f5760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61242161018082016101608301615331565b63ffffffff1661243961016083016101408401615331565b63ffffffff1610156124975760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b8060186124a48282615370565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906154a8565b61254b6040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b5f5f6125f189610df5565b5f8a8152600d602052604090205490915060ff166004816006811115612619576126196147a4565b148a600483909192612641576040516337e1404160e01b8152600401610a8493929190615204565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156126a4576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f8b8152600860205260409020600d016126c18a8c8361556d565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161270592919061529f565b6040519081900381206001600160e01b031960e084901b168252612733918c908c908c908c90600401615621565b602060405180830381865afa15801561274e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127729190615124565b935089898561279657604051632f9f8ab960e01b8152600401610a849291906152cd565b50506127a18b613bdd565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516127d39291906152cd565b60405180910390a28a5f5160206158555f395f51905f52600460056040516127fc92919061513f565b60405180910390a2505050979650505050505050565b61281a613827565b80515f5b81811015612879576001600b84838151811061283c5761283c614e58565b6020026020010151604051612851919061515a565b908152604051908190036020019020805491151560ff1990921691909117905560010161281e565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611afb9190615170565b5f546001600160a01b03163314806128cb57506003546001600160a01b031633145b6129175760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff1611801561292d5750600d60ff821611155b6129725760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b612990828260ff16600d81111561298b5761298b6147a4565b614059565b5050565b61299c613827565b6001600160a01b0381166129f25760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a8c5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612ad6575f5ffd5b505af1158015612ae8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c8291815260200190565b612b26613827565b6001600160a01b03811615801590612b5757505f828152600960205260409020546001600160a01b03828116911614155b8290612b79576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611afb565b612bd9613827565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612c206020860186614e3f565b6003811115612c3157612c316147a4565b6003811115612c4257612c426147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c69579050505050505090505f81600160028110612cc057612cc0614e58565b602002015163ffffffff1611835f016020810190612cde9190614e3f565b90612cfd5760405163286c068d60e11b8152600401610a849190614e6c565b5060208181015182516040805161018081018252601854815260195494810194909452601a5490840152601b546060840152601c546080840152601d5460a0840152601e5460c0840152601f546001600160a01b03811660e085015261ffff600160a01b82048116610100860152600160b01b82041661012085015263ffffffff600160c01b820481166101408601819052600160e01b90920481166101608601529283169392909116919015612dfd5761014081015163ffffffff16846001602002015163ffffffff161015865f016020810190612ddc9190614e3f565b90612dfb5760405163010b971d60e31b8152600401610a849190614e6c565b505b61016081015163ffffffff1615612e4c5761016081015184519063ffffffff9081169082161015612e4a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610a84565b505b60408601356020870135811015612e795760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016546015545f929190612e9960208b013560408c0135614e8e565b612ea39190614ea1565b612ead9190614ea1565b612eb79190614ea1565b90505f612ec5600186614e8e565b612ed0906002615659565b612edb906002615659565b612ee6906006614ea1565b90505f85845f0151612ef89190615659565b905081868560200151612f0b9190615659565b612f159190615659565b612f1f9082614ea1565b90506001861115612f67576002612f37600188614e8e565b612f419088615659565b8560400151612f509190615659565b612f5a9190615670565b612f649082614ea1565b90505b81868560c00151612f789190615659565b612f829190615659565b612f8c9082614ea1565b905082868560600151612f9f9190615659565b612fa99190615659565b612fb39082614ea1565b9050848460800151612fc59190615659565b612fcf9082614ea1565b90506001851115613017576002612fe7600187614e8e565b612ff19087615659565b85604001516130009190615659565b61300a9190615670565b6130149082614ea1565b90505b60a08401516130269082614ea1565b610100850151909150612710906130419061ffff1682614ea1565b61304b9083615659565b6130559190615670565b9750878061307957604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b61308e613827565b6001600160a01b038116158015906130b457506001546001600160a01b03828116911614155b81906130d4576040516320252f0b60e01b8152600401610a849190614740565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac908390614740565b613128613827565b6131356020820182615331565b63ffffffff1661314b6040830160208401615331565b63ffffffff161015801561317057505f6131686020830183615331565b63ffffffff16115b6131b05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156132b95761014081015163ffffffff1661326a6040840160208501615331565b63ffffffff1610156132b95760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff161561332d5761016081015163ffffffff166132e36020840184615331565b63ffffffff16101561332d5760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f856003811115613343576133436147a4565b6003811115613354576133546147a4565b815260208101919091526040015f2061336e9160026143f1565b50826003811115613381576133816147a4565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516133b0919061568f565b60405180910390a2505050565b6133c5613827565b6001600160a01b0381166133ee575f604051631e4fbdf760e01b8152600401610a849190614740565b610bc8816138c6565b5f818152600d602052604081205460ff168181600681111561341b5761341b6147a4565b0361344057826001826040516337e1404160e01b8152600401610a8493929190615204565b6005816006811115613454576134546147a4565b036134755760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613489576134896147a4565b036134aa57604051633de16e3560e11b815260048101849052602401610a84565b5f6134b58483613a55565b93509050806134da57604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115613523576135236147a4565b0217905550835f5160206158555f395f51905f5283600660405161354892919061513f565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516135829291906156cf565b60405180910390a25050919050565b613599613827565b6001600160a01b038116158015906135be57505f546001600160a01b03828116911614155b81906135de576040516375ac4eb760e11b8152600401610a849190614740565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac908390614740565b6001600160a01b0381165f90815260076020526040902054819060ff16156136655760405163b29d459560e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac908390614740565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6136ea6141b4565b610bc8816141d9565b80356137365760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f8160200135116137825760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116137d15760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b33613830611d81565b6001600160a01b031614611a6d573360405163118cdaa760e01b8152600401610a849190614740565b6040516001600160a01b0384811660248301528381166044830152606482018390526138c09186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506141e1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d81111561395e5761395e6147a4565b148061397b5750600281600d811115613979576139796147a4565b145b156139b3575f5b6040519080825280602002602001820160405280156139ab578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613a1957506040513d5f823e601f3d908101601f19168201604052613a1691908101906156ea565b60015b613a23575f613982565b9392505050565b613a5083846001600160a01b031663a9059cbb858560405160240161388e929190615779565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613acf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613af39190614fb4565b90506001856006811115613b0957613b096147a4565b148015613b1557508042115b15613b2857600180935093505050613bd6565b6002856006811115613b3c57613b3c6147a4565b148015613b495750815142115b15613b5d5760016003935093505050613bd6565b6003856006811115613b7157613b716147a4565b148015613b815750816020015142115b15613b955760016006935093505050613bd6565b6004856006811115613ba957613ba96147a4565b148015613bb95750816040015142115b15613bcd576001600a935093505050613bd6565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613c22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c4991908101906156ea565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ce7576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613cb390889088908690600401615792565b5f604051808303815f87803b158015613cca575f5ffd5b505af1158015613cdc573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d2757506001600160a01b03811615155b15613d6357612710613d3d61ffff841687615659565b613d479190615670565b92508215613d6357613d636001600160a01b0385168285613a2a565b5f613d6e8487614e8e565b9050865f03613e22575f898152601060205260409020546001600160a01b03168015801590613d9c57505f82115b15613db557613db56001600160a01b0387168284613a2a565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613de9908d908d908b90600401615792565b5f604051808303815f87803b158015613e00575f5ffd5b505af1158015613e12573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115613e3b57613e3b6144f3565b604051908082528060200260200182016040528015613e64578160200160208202803683370190505b5090505f613e728984615670565b90505f805b8a811015613eb15782848281518110613e9257613e92614e58565b6020908102919091010152613ea78383614ea1565b9150600101613e77565b505f613ebd8286614e8e565b90508015613efa578084613ed260018e614e8e565b81518110613ee257613ee2614e58565b60200260200101818151613ef69190614ea1565b9052505b600154613f14906001600160a01b038b8116911687614244565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f58939291906157f2565b5f604051808303815f87803b158015613f6f575f5ffd5b505af1158015613f81573d5f5f3e3d5ffd5b5050600154613f9f92506001600160a01b038c81169250165f614244565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613fd1929190615827565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b815260040161401d93929190615792565b5f604051808303815f87803b158015614034575f5ffd5b505af1158015614046573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561407d5761407d6147a4565b036140a257826001826040516337e1404160e01b8152600401610a8493929190615204565b60058160068111156140b6576140b66147a4565b036140d75760405163462c7bed60e01b815260048101849052602401610a84565b60068160068111156140eb576140eb6147a4565b0361410c57604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d811115614155576141556147a4565b0217905550825f5160206158555f395f51905f5282600660405161417a92919061513f565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516133b09291906156cf565b6141bc6142d4565b611a6d57604051631afcd79f60e31b815260040160405180910390fd5b6133c56141b4565b5f5f60205f8451602086015f885af180614200576040513d5f823e3d81fd5b50505f513d91508115614217578060011415614224565b6001600160a01b0384163b155b156138c05783604051635274afe760e01b8152600401610a849190614740565b5f836001600160a01b031663095ea7b38484604051602401614267929190615779565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506142a084826142ed565b6138c0576142ca84856001600160a01b031663095ea7b3865f60405160240161388e929190615779565b6138c084826141e1565b5f6142dd6136b8565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561432c5750811561431e578060011461432c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161435e61448d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156143e1579160200282015b828111156143e15782518255916020019190600101906143c6565b506143ed9291506144ab565b5090565b6001830191839082156143e1579160200282015f5b8382111561445057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614406565b80156144805782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614450565b50506143ed9291506144ab565b60405180604001604052806002906020820280368337509192915050565b5b808211156143ed575f81556001016144ac565b6001600160a01b0381168114610bc8575f5ffd5b80356144de816144bf565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561452f5761452f6144f3565b604052919050565b5f6001600160401b0382111561454f5761454f6144f3565b5060051b60200190565b5f82601f830112614568575f5ffd5b81356001600160401b03811115614581576145816144f3565b614594601f8201601f1916602001614507565b8181528460208386010111156145a8575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126145d3575f5ffd5b81356145e66145e182614537565b614507565b8082825260208201915060208360051b860101925085831115614607575f5ffd5b602085015b838110156146475780356001600160401b03811115614629575f5ffd5b614638886020838a0101614559565b8452506020928301920161460c565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614669575f5ffd5b8835614674816144bf565b97506020890135614684816144bf565b96506040890135614694816144bf565b955060608901356146a4816144bf565b945060808901356146b4816144bf565b935060a089013592506146ca8a60c08b016144e3565b91506101208901356001600160401b038111156146e5575f5ffd5b6146f18b828c016145c4565b9150509295985092959890939650565b5f60208284031215614711575f5ffd5b8135613a23816144bf565b5f6020828403121561472c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106144de575f5ffd5b5f5f60408385031215614773575f5ffd5b61477c83614754565b946020939093013593505050565b5f6060828403121561479a575f5ffd5b613a2383836144e3565b634e487b7160e01b5f52602160045260245ffd5b600e81106147c8576147c86147a4565b9052565b602081016136dc82846147b8565b600481106147c8576147c86147a4565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614828602082018f6147da565b8c60408201528b6060820152614841608082018c614733565b6101c060a08201525f6148586101c083018c6147ea565b82810360c084015261486a818c6147ea565b905061487960e084018b614733565b61488761010084018a614733565b87610120840152866101408401528281036101608401526148a881876147ea565b9150506148b9610180830185614733565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156138c05781518452602093840193909101906001016148d8565b805182525f602082015161490e60208501826147da565b5060408201516040840152606082015161492b60608501826148d5565b50608082015160a084015260a082015161494860c0850182614733565b5060c082015161020060e08501526149646102008501826147ea565b905060e083015184820361010086015261497e82826147ea565b915050610100830151614995610120860182614733565b506101208301516149aa610140860182614733565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149dc82826147ea565b9150506101a08301516149f36101c0860182614733565b506101c08301518015156101e08601526139ab565b602081525f613a2360208301846148f7565b5f60208284031215614a2a575f5ffd5b81356001600160401b03811115614a3f575f5ffd5b614a4b84828501614559565b949350505050565b5f60208284031215614a63575f5ffd5b81356001600160401b03811115614a78575f5ffd5b82016101008185031215613a23575f5ffd5b828152604060208201525f614a4b60408301846148f7565b5f60208284031215614ab2575f5ffd5b81356001600160401b03811115614ac7575f5ffd5b614a4b848285016145c4565b5f5f60408385031215614ae4575f5ffd5b823591506020830135614af6816144bf565b809150509250929050565b5f5f60408385031215614b12575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016136dc565b821515815260408101613a2360208301846147b8565b5f5f83601f840112614b68575f5ffd5b5081356001600160401b03811115614b7e575f5ffd5b602083019150836020828501011115613bd6575f5ffd5b5f5f5f5f5f60608688031215614ba9575f5ffd5b8535945060208601356001600160401b03811115614bc5575f5ffd5b614bd188828901614b58565b90955093505060408601356001600160401b03811115614bef575f5ffd5b614bfb88828901614b58565b969995985093965092949392505050565b5f610180828403128015614c1e575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8060e0840182614733565b50610100830151614c9861010084018261ffff169052565b50610120830151614cb061012084018261ffff169052565b50610140830151614cca61014084018263ffffffff169052565b50610160830151614ce461016084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614d01575f5ffd5b8735965060208801356001600160401b03811115614d1d575f5ffd5b614d298a828b01614b58565b90975095505060408801356001600160401b03811115614d47575f5ffd5b614d538a828b01614b58565b90955093505060608801356001600160401b03811115614d71575f5ffd5b614d7d8a828b01614b58565b989b979a50959850939692959293505050565b5f5f60408385031215614da1575f5ffd5b82359150602083013560ff81168114614af6575f5ffd5b600781106147c8576147c86147a4565b602081016136dc8284614db8565b5f5f60608385031215614de7575f5ffd5b614df083614754565b915083606084011115614e01575f5ffd5b50926020919091019150565b600181811c90821680614e2157607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614e4f575f5ffd5b613a2382614754565b634e487b7160e01b5f52603260045260245ffd5b602081016136dc82846147da565b634e487b7160e01b5f52601160045260245ffd5b818103818111156136dc576136dc614e7a565b808201808211156136dc576136dc614e7a565b5f60018201614ec557614ec5614e7a565b5060010190565b5f5f8335601e19843603018112614ee1575f5ffd5b8301803591506001600160401b03821115614efa575f5ffd5b602001915036819003821315613bd6575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614f2b575f5ffd5b8135613a2381614f0e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614f7d60a08301888a614f36565b8281036060840152614f90818789614f36565b90508281036080840152614fa5818587614f36565b9b9a5050505050505050505050565b5f60208284031215614fc4575f5ffd5b5051919050565b601f821115613a5057805f5260205f20601f840160051c81016020851015614ff05750805b601f840160051c820191505b8181101561500f575f8155600101614ffc565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615043576150436144f3565b615057816150518454614e0d565b84614fcb565b6020601f821160018114615084575f83156150725750848201515b61507c8482615016565b85555061500f565b5f84815260208120601f198516915b828110156150b35787850151825560209485019460019092019101615093565b50848210156150d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561511957815163ffffffff168352602092830192909101906001016150f4565b505050949350505050565b5f60208284031215615134575f5ffd5b8151613a2381614f0e565b6040810161514d8285614db8565b613a236020830184614db8565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156151c757603f198786030184526151b28583516147ea565b94506020938401939190910190600101615196565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016152186020830185614db8565b614a4b6040830184614db8565b5f8151808452602084019350602083015f5b8281101561525e5781516001600160a01b0316865260209586019590910190600101615237565b5093949350505050565b848152836020820152608060408201525f6152866080830185615225565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61432c606083018486614f36565b602081525f614a4b602083018486614f36565b61ffff81168114610bc8575f5ffd5b80356144de816152e0565b5f6020828403121561530a575f5ffd5b8135613a23816152e0565b63ffffffff81168114610bc8575f5ffd5b80356144de81615315565b5f60208284031215615341575f5ffd5b8135613a2381615315565b5f81356136dc816144bf565b5f81356136dc816152e0565b5f81356136dc81615315565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016153e06153c360e0850161534c565b82546001600160a01b0319166001600160a01b0391909116178255565b6154106153f06101008501615358565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154406154206101208501615358565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154746154506101408501615364565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613a506154846101608501615364565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016154f960e084016144d3565b61550660e0840182614733565b5061551461010084016152ef565b61ffff1661010083015261552b61012084016152ef565b61ffff166101208301526155426101408401615326565b63ffffffff1661014083015261555b6101608401615326565b63ffffffff8116610160840152614ce4565b6001600160401b03831115615584576155846144f3565b615598836155928354614e0d565b83614fcb565b5f601f8411600181146155c4575f85156155b25750838201355b6155bc8682615016565b84555061500f565b5f83815260208120601f198716915b828110156155f357868501358255602094850194600190920191016155d3565b508682101561560f575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f61563a606083018688614f36565b828103604084015261564d818587614f36565b98975050505050505050565b80820281158282048414176136dc576136dc614e7a565b5f8261568a57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156156c65781356156ab81615315565b63ffffffff1683526020928301929190910190600101615697565b50505092915050565b604081016156dd8285614db8565b613a2360208301846147b8565b5f602082840312156156fa575f5ffd5b81516001600160401b0381111561570f575f5ffd5b8201601f8101841361571f575f5ffd5b805161572d6145e182614537565b8082825260208201915060208360051b85010192508683111561574e575f5ffd5b6020840193505b8284101561432c578351615768816144bf565b825260209384019390910190615755565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6157aa6060830185615225565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561525e5781518652602095860195909101906001016157d4565b6001600160a01b03841681526060602082018190525f9061581590830185615225565b828103604084015261432c81856157c2565b604081525f6158396040830185615225565b828103602084015261584b81856157c2565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063c4ccafa2116100e0578063ea71aa571161008f578063ea71aa5714610783578063f0691cba14610796578063f2fde38b146107a9578063f81b8ef6146107bc578063fad8e111146107cf578063fbdb3237146107e2578063fd2f3d011461080a575f5ffd5b8063c4ccafa2146106dd578063cb649617146106ff578063cbd1687214610708578063cf0f34c41461071b578063cfbdc98d1461072e578063da16fb2f1461075d578063e59e469514610770575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610641578063ac3d2f4214610656578063b27392d51461067e578063b68fd1be14610691578063bb2d1b82146106a4578063bff232c1146106b7578063c1ab0f1f146106ca575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a0d4664f1461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614651565b61081d565b005b6102f0610300366004614701565b610a2a565b61032d61031336600461471c565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614740565b60405180910390f35b61032d61035136600461471c565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614762565b610ad6565b60405163ffffffff909116815260200161033a565b6102f06103a1366004614701565b610b12565b6102f06103b436600461478a565b610bb7565b6103db6103c736600461471c565b5f908152600f602052604090205460ff1690565b60405161033a91906147cc565b6103fb6103f636600461471c565b610bcb565b60405161033a9e9d9c9b9a99989796959493929190614818565b61042861042336600461471c565b610df5565b60405161033a9190614a08565b61045461044336600461471c565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614a1a565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae36600461471c565b6110f2565b6102f06104c1366004614701565b611181565b6104d96104d4366004614a53565b611214565b60405161033a929190614a8a565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611a5c565b6102f0610519366004614aa2565b611a6f565b6102f061052c366004614ad3565b611b07565b6102f061053f36600461471c565b611b90565b6102f0610552366004614b01565b611c8e565b60015461032d906001600160a01b031681565b61032d611d81565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611daf565b60405161033a9190614b21565b6102f06105ba36600461471c565b611df5565b61059f6105cd36600461471c565b611f9d565b6105e56105e036600461471c565b611ff6565b60405161033a929190614b42565b61032d61060136600461471c565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614b95565b61201d565b6102f061063c366004614c0c565b6122b5565b6106496124d6565b60405161033a9190614c26565b61032d61066436600461471c565b5f908152600a60205260409020546001600160a01b031690565b61049061068c366004614ceb565b6125e6565b6102f061069f366004614aa2565b612812565b6102f06106b2366004614d90565b6128a9565b6102f06106c5366004614701565b612994565b6102f06106d8366004614b01565b612a3b565b6104906106eb366004614701565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610716366004614ad3565b612b1e565b6102f061072936600461471c565b612bd1565b61075061073c36600461471c565b5f908152600d602052604090205460ff1690565b60405161033a9190614dc8565b61045461076b366004614a53565b612c0e565b6102f061077e366004614701565b613086565b6102f0610791366004614dd6565b613120565b60025461032d906001600160a01b031681565b6102f06107b7366004614701565b6133bd565b6103db6107ca36600461471c565b6133f7565b6102f06107dd366004614701565b613591565b61032d6107f036600461471c565b600a6020525f90815260409020546001600160a01b031681565b6102f0610818366004614701565b613629565b5f6108266136b8565b805490915060ff600160401b82041615906001600160401b03165f8115801561084c5750825b90505f826001600160401b031660011480156108675750303b155b905081158015610875575080155b156108935760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108bd57845460ff60401b1916600160401b1785555b6108c6336136e2565b6108cf88612bd1565b6108d88c613591565b6108e18b613086565b6108ea8a610a2a565b6108f389610b12565b6108fc876136f3565b61090586612812565b604080516101808101825261c3508082526161a860208301819052611388938301849052601460608401819052620249f0608085018190526207a12060a086018190526107d060c087018190525f60e088018190526103e86101008901526101208801819052610140880181905261016090970196909652601894909455601992909255601a94909455601b93909355601c92909255601d91909155601e55607d60a31b601f556109b4611d81565b6001600160a01b03168d6001600160a01b0316146109d5576109d58d6133bd565b8315610a1b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610a32613827565b6001600160a01b038116610a8d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610aef575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610b1a613827565b6001600160a01b03811615801590610b4057506004546001600160a01b03828116911614155b8190610b605760405163eddf07f560e01b8152600401610a849190614740565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610bac908390614740565b60405180910390a150565b610bbf613827565b610bc8816136f3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610c1690614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4290614e0d565b8015610c8d5780601f10610c6457610100808354040283529160200191610c8d565b820191905f5260205f20905b815481529060010190602001808311610c7057829003601f168201915b505050505090806008018054610ca290614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90614e0d565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610d5890614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8490614e0d565b8015610dcf5780601f10610da657610100808354040283529160200191610dcf565b820191905f5260205f20905b815481529060010190602001808311610db257829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610dfd614336565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610e3a57610e3a6147a4565b6003811115610e4b57610e4b6147a4565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610e705750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610ebd90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee990614e0d565b8015610f345780601f10610f0b57610100808354040283529160200191610f34565b820191905f5260205f20905b815481529060010190602001808311610f1757829003601f168201915b50505050508152602001600882018054610f4d90614e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990614e0d565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161101590614e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461104190614e0d565b801561108c5780601f106110635761010080835404028352916020019161108c565b820191905f5260205f20905b81548152906001019060200180831161106f57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110ec5760405163cd6f4a4f60e01b8152600401610a8491815260200190565b50919050565b6110fa613827565b5f8181526009602052604090205481906001600160a01b0316611133576040516381c4951960e01b8152600401610a8491815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610bac9083815260200190565b611189613827565b6001600160a01b0381165f90815260076020526040902054819060ff166111c4576040516321ac7c5f60e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610bac908390614740565b5f61121d614336565b5f60128161122e6020870187614e3f565b600381111561123f5761123f6147a4565b6003811115611250576112506147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611277579050505050505090505f816001600281106112ce576112ce614e58565b602002015163ffffffff1611845f0160208101906112ec9190614e3f565b9061130b5760405163286c068d60e11b8152600401610a849190614e6c565b5060208401354281101561133557604051630b99e87960e01b8152600401610a8491815260200190565b50604084013560208501358110156113635760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016545f919061137b426040890135614e8e565b6113859190614ea1565b61138f9190614ea1565b9050600554811081906113b8576040516313b783af60e21b8152600401610a8491815260200190565b5060075f6113cc6080880160608901614701565b6001600160a01b0316815260208101919091526040015f205460ff166113f86080870160608801614701565b906114175760405163295a6a6f60e11b8152600401610a849190614740565b505f61142286612c0e565b60068054965090915085905f61143783614eb4565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506115129190890135614ea1565b5f878152600e602090815260409091206001019190915581865261153890880188614e3f565b8560200190600381111561154e5761154e6147a4565b90816003811115611561576115616147a4565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526115a99060808901908901614701565b6001600160a01b031660a08601526115c46080880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261160c90880188614ecc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611659906101008901908901614f1b565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a086018190526004546116a9916001600160a01b03909116903085613859565b5f6116ba6080890160608a01614701565b6001600160a01b031663fefd9a8b88846116d760808d018d614ecc565b6116e460a08f018f614ecc565b8f8060c001906116f49190614ecc565b6040518963ffffffff1660e01b8152600401611717989796959493929190614f5e565b6020604051808303815f875af1158015611733573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117579190614fb4565b5f818152600960205260409020549091506001600160a01b03168181611793576040516381c4951960e01b8152600401610a8491815260200190565b505f828152600a60205260409020546001600160a01b031682816117cd576040516381c4951960e01b8152600401610a8491815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561182b5761182b6147a4565b0217905550604082015181600201556060820151816003019060026118519291906143b3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611896908261502a565b5060e082015160088201906118ab908261502a565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611913908261502a565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611979908c9088908c906004016150df565b6020604051808303815f875af1158015611995573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b99190615124565b6119d657604051630d8dbe2560e01b815260040160405180910390fd5b6119e660808b0160608c01614701565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611a20929190614a8a565b60405180910390a2885f5160206158555f395f51905f525f6001604051611a4892919061513f565b60405180910390a250505050505050915091565b611a64613827565b611a6d5f6138c6565b565b611a77613827565b80515f5b81811015611acb57600b838281518110611a9757611a97614e58565b6020026020010151604051611aac919061515a565b908152604051908190036020019020805460ff19169055600101611a7b565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611afb9190615170565b60405180910390a15050565b611b0f613827565b6001600160a01b03811615801590611b4057505f828152600a60205260409020546001600160a01b03828116911614155b8290611b62576040516381c4951960e01b8152600401610a8491815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611bb95760405162461bcd60e51b8152600401610a84906151d3565b5f818152600d602052604090205460ff166001816006811115611bde57611bde6147a4565b14611c0357816001826040516337e1404160e01b8152600401610a8493929190615204565b5f828152600d60205260409020805460ff19166002179055601554611c289042614ea1565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206158555f395f51905f5260016002604051611c8292919061513f565b60405180910390a25050565b5f546001600160a01b03163314611cb75760405162461bcd60e51b8152600401610a84906151d3565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611ce757611ce76147a4565b14611d0c57836002826040516337e1404160e01b8152600401610a8493929190615204565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206158555f395f51905f5260026003604051611d7392919061513f565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611dd060405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611e1a57611e1a6147a4565b14611e575760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610a84565b5f828152600c602052604090205480611ea95760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610a84565b5f838152600c60205260408120819055611ec284613936565b5f858152601160205260409020546002549192506001600160a01b0390811691611eef9183911685613a2a565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611f25908890879087908790600401615268565b5f604051808303815f87803b158015611f3c575f5ffd5b505af1158015611f4e573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611f8e929190918252602082015260400190565b60405180910390a25050505050565b611fbe60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166120138482613a55565b9250925050915091565b5f5f61202887610df5565b5f888152600d602052604090205490915060ff166003816006811115612050576120506147a4565b1488600383909192612078576040516337e1404160e01b8152600401610a8493929190615204565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156120dc576040516308f3034360e31b815260048101929092526024820152604401610a84565b50506060830151602001518990428111156121135760405163017e35e560e71b815260048101929092526024820152604401610a84565b505061016083015189901561213e57604051637eb9cea960e11b8152600401610a8491815260200190565b505f888860405161215092919061529f565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506121929042614ea1565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906121df908d9085908c908c906004016152ae565b6020604051808303815f875af11580156121fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221f9190615124565b945088888661224357604051632f9f8ab960e01b8152600401610a849291906152cd565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516122779291906152cd565b60405180910390a2895f5160206158555f395f51905f52600360046040516122a092919061513f565b60405180910390a25050505095945050505050565b6122bd613827565b6127106122d2610120830161010084016152fa565b61ffff16111561231a5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610a84565b61271061232f610140830161012084016152fa565b61ffff1611156123765760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610a84565b612388610140820161012083016152fa565b61ffff1615806123b157505f6123a5610100830160e08401614701565b6001600160a01b031614155b61240f5760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610a84565b61242161018082016101608301615331565b63ffffffff1661243961016083016101408401615331565b63ffffffff1610156124975760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610a84565b8060186124a48282615370565b9050507f3627e96aacd566e39ff214d04e683118b17004f7996050a64f99c1d44d1318b581604051610bac91906154a8565b61254b6040518061018001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f6001600160a01b031681526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f63ffffffff1681525090565b50604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b82048116610140840152600160e01b9091041661016082015290565b5f5f6125f189610df5565b5f8a8152600d602052604090205490915060ff166004816006811115612619576126196147a4565b148a600483909192612641576040516337e1404160e01b8152600401610a8493929190615204565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156126a4576040516308f3034360e31b815260048101929092526024820152604401610a84565b50505f8b8152600860205260409020600d016126c18a8c8361556d565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161270592919061529f565b6040519081900381206001600160e01b031960e084901b168252612733918c908c908c908c90600401615621565b602060405180830381865afa15801561274e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127729190615124565b935089898561279657604051632f9f8ab960e01b8152600401610a849291906152cd565b50506127a18b613bdd565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516127d39291906152cd565b60405180910390a28a5f5160206158555f395f51905f52600460056040516127fc92919061513f565b60405180910390a2505050979650505050505050565b61281a613827565b80515f5b81811015612879576001600b84838151811061283c5761283c614e58565b6020026020010151604051612851919061515a565b908152604051908190036020019020805491151560ff1990921691909117905560010161281e565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611afb9190615170565b5f546001600160a01b03163314806128cb57506003546001600160a01b031633145b6129175760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610a84565b5f8160ff1611801561292d5750600d60ff821611155b6129725760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610a84565b612990828260ff16600d81111561298b5761298b6147a4565b614059565b5050565b61299c613827565b6001600160a01b0381166129f25760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610a84565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612a8c5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610a84565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612ad6575f5ffd5b505af1158015612ae8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611c8291815260200190565b612b26613827565b6001600160a01b03811615801590612b5757505f828152600960205260409020546001600160a01b03828116911614155b8290612b79576040516381c4951960e01b8152600401610a8491815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611afb565b612bd9613827565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610bac565b5f80601281612c206020860186614e3f565b6003811115612c3157612c316147a4565b6003811115612c4257612c426147a4565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612c69579050505050505090505f81600160028110612cc057612cc0614e58565b602002015163ffffffff1611835f016020810190612cde9190614e3f565b90612cfd5760405163286c068d60e11b8152600401610a849190614e6c565b5060208181015182516040805161018081018252601854815260195494810194909452601a5490840152601b546060840152601c546080840152601d5460a0840152601e5460c0840152601f546001600160a01b03811660e085015261ffff600160a01b82048116610100860152600160b01b82041661012085015263ffffffff600160c01b820481166101408601819052600160e01b90920481166101608601529283169392909116919015612dfd5761014081015163ffffffff16846001602002015163ffffffff161015865f016020810190612ddc9190614e3f565b90612dfb5760405163010b971d60e31b8152600401610a849190614e6c565b505b61016081015163ffffffff1615612e4c5761016081015184519063ffffffff9081169082161015612e4a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610a84565b505b60408601356020870135811015612e795760405163174b5a0760e21b8152600401610a8491815260200190565b506017546016546015545f929190612e9960208b013560408c0135614e8e565b612ea39190614ea1565b612ead9190614ea1565b612eb79190614ea1565b90505f612ec5600186614e8e565b612ed0906002615659565b612edb906002615659565b612ee6906006614ea1565b90505f85845f0151612ef89190615659565b905081868560200151612f0b9190615659565b612f159190615659565b612f1f9082614ea1565b90506001861115612f67576002612f37600188614e8e565b612f419088615659565b8560400151612f509190615659565b612f5a9190615670565b612f649082614ea1565b90505b81868560c00151612f789190615659565b612f829190615659565b612f8c9082614ea1565b905082868560600151612f9f9190615659565b612fa99190615659565b612fb39082614ea1565b9050848460800151612fc59190615659565b612fcf9082614ea1565b90506001851115613017576002612fe7600187614e8e565b612ff19087615659565b85604001516130009190615659565b61300a9190615670565b6130149082614ea1565b90505b60a08401516130269082614ea1565b610100850151909150612710906130419061ffff1682614ea1565b61304b9083615659565b6130559190615670565b9750878061307957604051638c4fcd9360e01b8152600401610a8491815260200190565b5050505050505050919050565b61308e613827565b6001600160a01b038116158015906130b457506001546001600160a01b03828116911614155b81906130d4576040516320252f0b60e01b8152600401610a849190614740565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610bac908390614740565b613128613827565b6131356020820182615331565b63ffffffff1661314b6040830160208401615331565b63ffffffff161015801561317057505f6131686020830183615331565b63ffffffff16115b6131b05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610a84565b604080516101808101825260185481526019546020820152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82041661012083015263ffffffff600160c01b820481166101408401819052600160e01b90920416610160830152156132b95761014081015163ffffffff1661326a6040840160208501615331565b63ffffffff1610156132b95760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610a84565b61016081015163ffffffff161561332d5761016081015163ffffffff166132e36020840184615331565b63ffffffff16101561332d5760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610a84565b8160125f856003811115613343576133436147a4565b6003811115613354576133546147a4565b815260208101919091526040015f2061336e9160026143f1565b50826003811115613381576133816147a4565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516133b0919061568f565b60405180910390a2505050565b6133c5613827565b6001600160a01b0381166133ee575f604051631e4fbdf760e01b8152600401610a849190614740565b610bc8816138c6565b5f818152600d602052604081205460ff168181600681111561341b5761341b6147a4565b0361344057826001826040516337e1404160e01b8152600401610a8493929190615204565b6005816006811115613454576134546147a4565b036134755760405163462c7bed60e01b815260048101849052602401610a84565b6006816006811115613489576134896147a4565b036134aa57604051633de16e3560e11b815260048101849052602401610a84565b5f6134b58483613a55565b93509050806134da57604051639f65d93560e01b815260048101859052602401610a84565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115613523576135236147a4565b0217905550835f5160206158555f395f51905f5283600660405161354892919061513f565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516135829291906156cf565b60405180910390a25050919050565b613599613827565b6001600160a01b038116158015906135be57505f546001600160a01b03828116911614155b81906135de576040516375ac4eb760e11b8152600401610a849190614740565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610bac908390614740565b6001600160a01b0381165f90815260076020526040902054819060ff16156136655760405163b29d459560e01b8152600401610a849190614740565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610bac908390614740565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6136ea6141b4565b610bc8816141d9565b80356137365760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610a84565b5f8160200135116137825760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610a84565b5f8160400135116137d15760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610a84565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610bac565b33613830611d81565b6001600160a01b031614611a6d573360405163118cdaa760e01b8152600401610a849190614740565b6040516001600160a01b0384811660248301528381166044830152606482018390526138c09186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506141e1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d81111561395e5761395e6147a4565b148061397b5750600281600d811115613979576139796147a4565b145b156139b3575f5b6040519080825280602002602001820160405280156139ab578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613a1957506040513d5f823e601f3d908101601f19168201604052613a1691908101906156ea565b60015b613a23575f613982565b9392505050565b613a5083846001600160a01b031663a9059cbb858560405160240161388e929190615779565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613acf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613af39190614fb4565b90506001856006811115613b0957613b096147a4565b148015613b1557508042115b15613b2857600180935093505050613bd6565b6002856006811115613b3c57613b3c6147a4565b148015613b495750815142115b15613b5d5760016003935093505050613bd6565b6003856006811115613b7157613b716147a4565b148015613b815750816020015142115b15613b955760016006935093505050613bd6565b6004856006811115613ba957613ba96147a4565b148015613bb95750816040015142115b15613bcd576001600a935093505050613bd6565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613c22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c4991908101906156ea565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ce7576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613cb390889088908690600401615792565b5f604051808303815f87803b158015613cca575f5ffd5b505af1158015613cdc573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d2757506001600160a01b03811615155b15613d6357612710613d3d61ffff841687615659565b613d479190615670565b92508215613d6357613d636001600160a01b0385168285613a2a565b5f613d6e8487614e8e565b9050865f03613e22575f898152601060205260409020546001600160a01b03168015801590613d9c57505f82115b15613db557613db56001600160a01b0387168284613a2a565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613de9908d908d908b90600401615792565b5f604051808303815f87803b158015613e00575f5ffd5b505af1158015613e12573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115613e3b57613e3b6144f3565b604051908082528060200260200182016040528015613e64578160200160208202803683370190505b5090505f613e728984615670565b90505f805b8a811015613eb15782848281518110613e9257613e92614e58565b6020908102919091010152613ea78383614ea1565b9150600101613e77565b505f613ebd8286614e8e565b90508015613efa578084613ed260018e614e8e565b81518110613ee257613ee2614e58565b60200260200101818151613ef69190614ea1565b9052505b600154613f14906001600160a01b038b8116911687614244565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f58939291906157f2565b5f604051808303815f87803b158015613f6f575f5ffd5b505af1158015613f81573d5f5f3e3d5ffd5b5050600154613f9f92506001600160a01b038c81169250165f614244565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613fd1929190615827565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b815260040161401d93929190615792565b5f604051808303815f87803b158015614034575f5ffd5b505af1158015614046573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561407d5761407d6147a4565b036140a257826001826040516337e1404160e01b8152600401610a8493929190615204565b60058160068111156140b6576140b66147a4565b036140d75760405163462c7bed60e01b815260048101849052602401610a84565b60068160068111156140eb576140eb6147a4565b0361410c57604051633de16e3560e11b815260048101849052602401610a84565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d811115614155576141556147a4565b0217905550825f5160206158555f395f51905f5282600660405161417a92919061513f565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516133b09291906156cf565b6141bc6142d4565b611a6d57604051631afcd79f60e31b815260040160405180910390fd5b6133c56141b4565b5f5f60205f8451602086015f885af180614200576040513d5f823e3d81fd5b50505f513d91508115614217578060011415614224565b6001600160a01b0384163b155b156138c05783604051635274afe760e01b8152600401610a849190614740565b5f836001600160a01b031663095ea7b38484604051602401614267929190615779565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506142a084826142ed565b6138c0576142ca84856001600160a01b031663095ea7b3865f60405160240161388e929190615779565b6138c084826141e1565b5f6142dd6136b8565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561432c5750811561431e578060011461432c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161435e61448d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156143e1579160200282015b828111156143e15782518255916020019190600101906143c6565b506143ed9291506144ab565b5090565b6001830191839082156143e1579160200282015f5b8382111561445057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614406565b80156144805782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614450565b50506143ed9291506144ab565b60405180604001604052806002906020820280368337509192915050565b5b808211156143ed575f81556001016144ac565b6001600160a01b0381168114610bc8575f5ffd5b80356144de816144bf565b919050565b5f606082840312156110ec575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561452f5761452f6144f3565b604052919050565b5f6001600160401b0382111561454f5761454f6144f3565b5060051b60200190565b5f82601f830112614568575f5ffd5b81356001600160401b03811115614581576145816144f3565b614594601f8201601f1916602001614507565b8181528460208386010111156145a8575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126145d3575f5ffd5b81356145e66145e182614537565b614507565b8082825260208201915060208360051b860101925085831115614607575f5ffd5b602085015b838110156146475780356001600160401b03811115614629575f5ffd5b614638886020838a0101614559565b8452506020928301920161460c565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614669575f5ffd5b8835614674816144bf565b97506020890135614684816144bf565b96506040890135614694816144bf565b955060608901356146a4816144bf565b945060808901356146b4816144bf565b935060a089013592506146ca8a60c08b016144e3565b91506101208901356001600160401b038111156146e5575f5ffd5b6146f18b828c016145c4565b9150509295985092959890939650565b5f60208284031215614711575f5ffd5b8135613a23816144bf565b5f6020828403121561472c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106144de575f5ffd5b5f5f60408385031215614773575f5ffd5b61477c83614754565b946020939093013593505050565b5f6060828403121561479a575f5ffd5b613a2383836144e3565b634e487b7160e01b5f52602160045260245ffd5b600e81106147c8576147c86147a4565b9052565b602081016136dc82846147b8565b600481106147c8576147c86147a4565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614828602082018f6147da565b8c60408201528b6060820152614841608082018c614733565b6101c060a08201525f6148586101c083018c6147ea565b82810360c084015261486a818c6147ea565b905061487960e084018b614733565b61488761010084018a614733565b87610120840152866101408401528281036101608401526148a881876147ea565b9150506148b9610180830185614733565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156138c05781518452602093840193909101906001016148d8565b805182525f602082015161490e60208501826147da565b5060408201516040840152606082015161492b60608501826148d5565b50608082015160a084015260a082015161494860c0850182614733565b5060c082015161020060e08501526149646102008501826147ea565b905060e083015184820361010086015261497e82826147ea565b915050610100830151614995610120860182614733565b506101208301516149aa610140860182614733565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149dc82826147ea565b9150506101a08301516149f36101c0860182614733565b506101c08301518015156101e08601526139ab565b602081525f613a2360208301846148f7565b5f60208284031215614a2a575f5ffd5b81356001600160401b03811115614a3f575f5ffd5b614a4b84828501614559565b949350505050565b5f60208284031215614a63575f5ffd5b81356001600160401b03811115614a78575f5ffd5b82016101008185031215613a23575f5ffd5b828152604060208201525f614a4b60408301846148f7565b5f60208284031215614ab2575f5ffd5b81356001600160401b03811115614ac7575f5ffd5b614a4b848285016145c4565b5f5f60408385031215614ae4575f5ffd5b823591506020830135614af6816144bf565b809150509250929050565b5f5f60408385031215614b12575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016136dc565b821515815260408101613a2360208301846147b8565b5f5f83601f840112614b68575f5ffd5b5081356001600160401b03811115614b7e575f5ffd5b602083019150836020828501011115613bd6575f5ffd5b5f5f5f5f5f60608688031215614ba9575f5ffd5b8535945060208601356001600160401b03811115614bc5575f5ffd5b614bd188828901614b58565b90955093505060408601356001600160401b03811115614bef575f5ffd5b614bfb88828901614b58565b969995985093965092949392505050565b5f610180828403128015614c1e575f5ffd5b509092915050565b5f61018082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8060e0840182614733565b50610100830151614c9861010084018261ffff169052565b50610120830151614cb061012084018261ffff169052565b50610140830151614cca61014084018263ffffffff169052565b50610160830151614ce461016084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614d01575f5ffd5b8735965060208801356001600160401b03811115614d1d575f5ffd5b614d298a828b01614b58565b90975095505060408801356001600160401b03811115614d47575f5ffd5b614d538a828b01614b58565b90955093505060608801356001600160401b03811115614d71575f5ffd5b614d7d8a828b01614b58565b989b979a50959850939692959293505050565b5f5f60408385031215614da1575f5ffd5b82359150602083013560ff81168114614af6575f5ffd5b600781106147c8576147c86147a4565b602081016136dc8284614db8565b5f5f60608385031215614de7575f5ffd5b614df083614754565b915083606084011115614e01575f5ffd5b50926020919091019150565b600181811c90821680614e2157607f821691505b6020821081036110ec57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614e4f575f5ffd5b613a2382614754565b634e487b7160e01b5f52603260045260245ffd5b602081016136dc82846147da565b634e487b7160e01b5f52601160045260245ffd5b818103818111156136dc576136dc614e7a565b808201808211156136dc576136dc614e7a565b5f60018201614ec557614ec5614e7a565b5060010190565b5f5f8335601e19843603018112614ee1575f5ffd5b8301803591506001600160401b03821115614efa575f5ffd5b602001915036819003821315613bd6575f5ffd5b8015158114610bc8575f5ffd5b5f60208284031215614f2b575f5ffd5b8135613a2381614f0e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f614f7d60a08301888a614f36565b8281036060840152614f90818789614f36565b90508281036080840152614fa5818587614f36565b9b9a5050505050505050505050565b5f60208284031215614fc4575f5ffd5b5051919050565b601f821115613a5057805f5260205f20601f840160051c81016020851015614ff05750805b601f840160051c820191505b8181101561500f575f8155600101614ffc565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615043576150436144f3565b615057816150518454614e0d565b84614fcb565b6020601f821160018114615084575f83156150725750848201515b61507c8482615016565b85555061500f565b5f84815260208120601f198516915b828110156150b35787850151825560209485019460019092019101615093565b50848210156150d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561511957815163ffffffff168352602092830192909101906001016150f4565b505050949350505050565b5f60208284031215615134575f5ffd5b8151613a2381614f0e565b6040810161514d8285614db8565b613a236020830184614db8565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156151c757603f198786030184526151b28583516147ea565b94506020938401939190910190600101615196565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016152186020830185614db8565b614a4b6040830184614db8565b5f8151808452602084019350602083015f5b8281101561525e5781516001600160a01b0316865260209586019590910190600101615237565b5093949350505050565b848152836020820152608060408201525f6152866080830185615225565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61432c606083018486614f36565b602081525f614a4b602083018486614f36565b61ffff81168114610bc8575f5ffd5b80356144de816152e0565b5f6020828403121561530a575f5ffd5b8135613a23816152e0565b63ffffffff81168114610bc8575f5ffd5b80356144de81615315565b5f60208284031215615341575f5ffd5b8135613a2381615315565b5f81356136dc816144bf565b5f81356136dc816152e0565b5f81356136dc81615315565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016153e06153c360e0850161534c565b82546001600160a01b0319166001600160a01b0391909116178255565b6154106153f06101008501615358565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154406154206101208501615358565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154746154506101408501615364565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b613a506154846101608501615364565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c0808301359082015261018081016154f960e084016144d3565b61550660e0840182614733565b5061551461010084016152ef565b61ffff1661010083015261552b61012084016152ef565b61ffff166101208301526155426101408401615326565b63ffffffff1661014083015261555b6101608401615326565b63ffffffff8116610160840152614ce4565b6001600160401b03831115615584576155846144f3565b615598836155928354614e0d565b83614fcb565b5f601f8411600181146155c4575f85156155b25750838201355b6155bc8682615016565b84555061500f565b5f83815260208120601f198716915b828110156155f357868501358255602094850194600190920191016155d3565b508682101561560f575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f61563a606083018688614f36565b828103604084015261564d818587614f36565b98975050505050505050565b80820281158282048414176136dc576136dc614e7a565b5f8261568a57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156156c65781356156ab81615315565b63ffffffff1683526020928301929190910190600101615697565b50505092915050565b604081016156dd8285614db8565b613a2360208301846147b8565b5f602082840312156156fa575f5ffd5b81516001600160401b0381111561570f575f5ffd5b8201601f8101841361571f575f5ffd5b805161572d6145e182614537565b8082825260208201915060208360051b85010192508683111561574e575f5ffd5b6020840193505b8284101561432c578351615768816144bf565b825260209384019390910190615755565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6157aa6060830185615225565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561525e5781518652602095860195909101906001016157d4565b6001600160a01b03841681526060602082018190525f9061581590830185615225565b828103604084015261432c81856157c2565b604081525f6158396040830185615225565b828103602084015261584b81856157c2565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615ca0806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461492c565b61095a565b005b6102f06103003660046149dc565b610ba1565b61032d6103133660046149f7565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614a1b565b60405180910390f35b61032d6103513660046149f7565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614a3d565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046149dc565b610c89565b6102f06103b4366004614a65565b610d2e565b6103db6103c73660046149f7565b5f908152600f602052604090205460ff1690565b60405161033a9190614aa7565b6103fb6103f63660046149f7565b610d42565b60405161033a9e9d9c9b9a99989796959493929190614af3565b6104286104233660046149f7565b610f6c565b60405161033a9190614ce3565b6104546104433660046149f7565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614cf5565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046149f7565b611269565b6102f06104c13660046149dc565b6112f8565b6104d96104d4366004614d2e565b61138b565b60405161033a929190614d65565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614d7d565b611be6565b6102f061052c366004614dae565b611c7e565b6102f061053f3660046149f7565b611d07565b6102f0610552366004614ddc565b611e05565b60015461032d906001600160a01b031681565b61032d611ef8565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f26565b60405161033a9190614dfc565b6102f06105ba3660046149f7565b611f6c565b61059f6105cd3660046149f7565b612114565b6105e56105e03660046149f7565b61216d565b60405161033a929190614e1d565b61032d6106013660046149f7565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614e70565b612194565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ee7565b61032d61078e3660046149f7565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614ff4565b61242c565b6102f06107c9366004614d7d565b61265c565b6102f06107dc366004615099565b6126f3565b6102f06107ef3660046149dc565b6127de565b6102f0610802366004614ddc565b612885565b6104906108153660046149dc565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614dae565b612968565b6102f06108533660046149f7565b612a1b565b61087a6108663660046149f7565b5f908152600d602052604090205460ff1690565b60405161033a91906150d1565b6102f06108953660046150df565b612a58565b6104546108a8366004614d2e565b612dae565b6102f06108bb3660046149dc565b613332565b6102f06108ce3660046150f9565b6133cc565b60025461032d906001600160a01b031681565b6102f06108f43660046149dc565b613698565b6103db6109073660046149f7565b6136d2565b6102f061091a3660046149dc565b61386c565b61032d61092d3660046149f7565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046149dc565b613904565b5f610963613993565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a03336139bd565b610a0c88612a1b565b610a158c61386c565b610a1e8b613332565b610a278a610ba1565b610a3089610c89565b610a39876139ce565b610a428661265c565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611ef8565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613698565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613b02565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613b02565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb9190614a1b565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d23908390614a1b565b60405180910390a150565b610d36613b02565b610d3f816139ce565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990615130565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590615130565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90615130565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614611565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614a7f565b6003811115610fc257610fc2614a7f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490615130565b80601f016020809104026020016040519081016040528092919081815260200182805461106090615130565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490615130565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090615130565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90615130565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890615130565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613b02565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613b02565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d23908390614a1b565b5f611394614611565b5f6012816113a56020870187615162565b60038111156113b6576113b6614a7f565b60038111156113c7576113c7614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f816001600281106114455761144561517b565b602002015163ffffffff1611845f0160208101906114639190615162565b906114825760405163286c068d60e11b8152600401610bfb919061518f565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f24260408901356151b1565b6114fc91906151c4565b61150691906151c4565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016149dc565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016149dc565b9061158e5760405163295a6a6f60e11b8152600401610bfb9190614a1b565b505f61159986612dae565b60068054965090915085905f6115ae836151d7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff19166001179055601090945282902080543394169390931790925560165491925061168991908901356151c4565b5f878152600e60209081526040909120600101919091558186526116af90880188615162565b856020019060038111156116c5576116c5614a7f565b908160038111156116d8576116d8614a7f565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016149dc565b6001600160a01b031660a086015261173b60808801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c080870191909152611783908801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d090610100890190890161523e565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613b34565b5f6118316080890160608a016149dc565b6001600160a01b031663fefd9a8b888461184e60808d018d6151ef565b61185b60a08f018f6151ef565b8f8060c0019061186b91906151ef565b6040518963ffffffff1660e01b815260040161188e989796959493929190615281565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906152d7565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614a7f565b0217905550604082015181600201556060820151816003019060026119c892919061468e565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d908261534d565b5060e08201516008820190611a22908261534d565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a908261534d565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615402565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b309190615447565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016149dc565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614d65565b60405180910390a2885f516020615c745f395f51905f525f6001604051611bbf929190615462565b60405180910390a250505050505050915091565b611bdb613b02565b611be45f613ba1565b565b611bee613b02565b80515f5b81811015611c4257600b838281518110611c0e57611c0e61517b565b6020026020010151604051611c23919061547d565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615493565b60405180910390a15050565b611c86613b02565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d305760405162461bcd60e51b8152600401610bfb906154f6565b5f818152600d602052604090205460ff166001816006811115611d5557611d55614a7f565b14611d7a57816001826040516337e1404160e01b8152600401610bfb93929190615527565b5f828152600d60205260409020805460ff19166002179055601554611d9f90426151c4565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615c745f395f51905f5260016002604051611df9929190615462565b60405180910390a25050565b5f546001600160a01b03163314611e2e5760405162461bcd60e51b8152600401610bfb906154f6565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e5e57611e5e614a7f565b14611e8357836002826040516337e1404160e01b8152600401610bfb93929190615527565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615c745f395f51905f5260026003604051611eea929190615462565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9157611f91614a7f565b14611fce5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610bfb565b5f828152600c6020526040902054806120205760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610bfb565b5f838152600c6020526040812081905561203984613c11565b5f858152601160205260409020546002549192506001600160a01b03908116916120669183911685613d05565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061209c90889087908790879060040161558b565b5f604051808303815f87803b1580156120b3575f5ffd5b505af11580156120c5573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612105929190918252602082015260400190565b60405180910390a25050505050565b61213560405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661218a8482613d30565b9250925050915091565b5f5f61219f87610f6c565b5f888152600d602052604090205490915060ff1660038160068111156121c7576121c7614a7f565b14886003839091926121ef576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015612253576040516308f3034360e31b815260048101929092526024820152604401610bfb565b505060608301516020015189904281111561228a5760405163017e35e560e71b815260048101929092526024820152604401610bfb565b50506101608301518990156122b557604051637eb9cea960e11b8152600401610bfb91815260200190565b505f88886040516122c79291906155c2565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560175490915061230990426151c4565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90612356908d9085908c908c906004016155d1565b6020604051808303815f875af1158015612372573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123969190615447565b94508888866123ba57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123ee9291906155f0565b60405180910390a2895f516020615c745f395f51905f5260036004604051612417929190615462565b60405180910390a25050505095945050505050565b5f5f61243789610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561245f5761245f614a7f565b148a600483909192612487576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124ea576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016125078a8c83615603565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161254b9291906155c2565b6040519081900381206001600160e01b031960e084901b168252612579918c908c908c908c906004016156b7565b602060405180830381865afa158015612594573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125b89190615447565b93508989856125dc57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b50506125e78b613eb8565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161261d94939291906156ef565b60405180910390a28a5f516020615c745f395f51905f5260046005604051612646929190615462565b60405180910390a2505050979650505050505050565b612664613b02565b80515f5b818110156126c3576001600b8483815181106126865761268661517b565b602002602001015160405161269b919061547d565b908152604051908190036020019020805491151560ff19909216919091179055600101612668565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615493565b5f546001600160a01b031633148061271557506003546001600160a01b031633145b6127615760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610bfb565b5f8160ff161180156127775750600d60ff821611155b6127bc5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b6127da828260ff16600d8111156127d5576127d5614a7f565b614334565b5050565b6127e6613b02565b6001600160a01b03811661283c5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610bfb565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612920575f5ffd5b505af1158015612932573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611df991815260200190565b612970613b02565b6001600160a01b038116158015906129a157505f828152600960205260409020546001600160a01b03828116911614155b82906129c3576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612a23613b02565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b612a60613b02565b612710612a756101208301610100840161573a565b61ffff161115612abd5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610bfb565b612710612ad26101408301610120840161573a565b61ffff161115612b195760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610bfb565b612710612b2e6101608301610140840161573a565b61ffff161115612b805760405162461bcd60e51b815260206004820152601c60248201527f444b47207574696c697a6174696f6e20657863656564732031303025000000006044820152606401610bfb565b612710612b956101808301610160840161573a565b61ffff161115612be75760405162461bcd60e51b815260206004820181905260248201527f436f6d70757465207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612710612bfc6101a08301610180840161573a565b61ffff161115612c4e5760405162461bcd60e51b815260206004820181905260248201527f44656372797074207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612c606101408201610120830161573a565b61ffff161580612c8957505f612c7d610100830160e084016149dc565b6001600160a01b031614155b612ce75760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610bfb565b612cf96101e082016101c08301615771565b63ffffffff16612d116101c083016101a08401615771565b63ffffffff161015612d6f5760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610bfb565b806018612d7c82826157b0565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d23919061596e565b5f80601281612dc06020860186615162565b6003811115612dd157612dd1614a7f565b6003811115612de257612de2614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612e09579050505050505090505f81600160028110612e6057612e6061517b565b602002015163ffffffff1611835f016020810190612e7e9190615162565b90612e9d5760405163286c068d60e11b8152600401610bfb919061518f565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612fc8576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612fa79190615162565b90612fc65760405163010b971d60e31b8152600401610bfb919061518f565b505b6101c081015163ffffffff1615613017576101c081015184519063ffffffff908116908216101561301557604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b604086013560208701358110156130445760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f91612710916130629161ffff1690615a78565b61306c9190615a8f565b61271061ffff1683610160015161ffff1660156001015461308d9190615a78565b6130979190615a8f565b61271061ffff1684610140015161ffff1660155f01546130b79190615a78565b6130c19190615a8f565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa15801561310d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313191906152d7565b61313b91906151c4565b61314591906151b1565b61314f91906151c4565b61315991906151c4565b61316391906151c4565b90505f6131716001866151b1565b61317c906002615a78565b613187906002615a78565b6131929060066151c4565b90505f85845f01516131a49190615a78565b9050818685602001516131b79190615a78565b6131c19190615a78565b6131cb90826151c4565b905060018611156132135760026131e36001886151b1565b6131ed9088615a78565b85604001516131fc9190615a78565b6132069190615a8f565b61321090826151c4565b90505b81868560c001516132249190615a78565b61322e9190615a78565b61323890826151c4565b90508286856060015161324b9190615a78565b6132559190615a78565b61325f90826151c4565b90508484608001516132719190615a78565b61327b90826151c4565b905060018511156132c35760026132936001876151b1565b61329d9087615a78565b85604001516132ac9190615a78565b6132b69190615a8f565b6132c090826151c4565b90505b60a08401516132d290826151c4565b610100850151909150612710906132ed9061ffff16826151c4565b6132f79083615a78565b6133019190615a8f565b9750878061332557604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b61333a613b02565b6001600160a01b0381161580159061336057506001546001600160a01b03828116911614155b8190613380576040516320252f0b60e01b8152600401610bfb9190614a1b565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d23908390614a1b565b6133d4613b02565b6133e16020820182615771565b63ffffffff166133f76040830160208401615771565b63ffffffff161015801561341c57505f6134146020830183615771565b63ffffffff16115b61345c5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610bfb565b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215613594576101a081015163ffffffff166135456040840160208501615771565b63ffffffff1610156135945760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610bfb565b6101c081015163ffffffff1615613608576101c081015163ffffffff166135be6020840184615771565b63ffffffff1610156136085760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610bfb565b8160125f85600381111561361e5761361e614a7f565b600381111561362f5761362f614a7f565b815260208101919091526040015f206136499160026146cc565b5082600381111561365c5761365c614a7f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161368b9190615aae565b60405180910390a2505050565b6136a0613b02565b6001600160a01b0381166136c9575f604051631e4fbdf760e01b8152600401610bfb9190614a1b565b610d3f81613ba1565b5f818152600d602052604081205460ff16818160068111156136f6576136f6614a7f565b0361371b57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561372f5761372f614a7f565b036137505760405163462c7bed60e01b815260048101849052602401610bfb565b600681600681111561376457613764614a7f565b0361378557604051633de16e3560e11b815260048101849052602401610bfb565b5f6137908483613d30565b93509050806137b557604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156137fe576137fe614a7f565b0217905550835f516020615c745f395f51905f52836006604051613823929190615462565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161385d929190615aee565b60405180910390a25050919050565b613874613b02565b6001600160a01b0381161580159061389957505f546001600160a01b03828116911614155b81906138b9576040516375ac4eb760e11b8152600401610bfb9190614a1b565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d23908390614a1b565b6001600160a01b0381165f90815260076020526040902054819060ff16156139405760405163b29d459560e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d23908390614a1b565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6139c561448f565b610d3f816144b4565b8035613a115760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610bfb565b5f816020013511613a5d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610bfb565b5f816040013511613aac5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610bfb565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b33613b0b611ef8565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb9190614a1b565b6040516001600160a01b038481166024830152838116604483015260648201839052613b9b9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506144bc565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613c3957613c39614a7f565b1480613c565750600281600d811115613c5457613c54614a7f565b145b15613c8e575f5b604051908082528060200260200182016040528015613c86578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613cf457506040513d5f823e601f3d908101601f19168201604052613cf19190810190615b09565b60015b613cfe575f613c5d565b9392505050565b613d2b83846001600160a01b031663a9059cbb8585604051602401613b69929190615b98565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613daa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dce91906152d7565b90506001856006811115613de457613de4614a7f565b148015613df057508042115b15613e0357600180935093505050613eb1565b6002856006811115613e1757613e17614a7f565b148015613e245750815142115b15613e385760016003935093505050613eb1565b6003856006811115613e4c57613e4c614a7f565b148015613e5c5750816020015142115b15613e705760016006935093505050613eb1565b6004856006811115613e8457613e84614a7f565b148015613e945750816040015142115b15613ea8576001600a935093505050613eb1565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613efd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613f249190810190615b09565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613fc2576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613f8e90889088908690600401615bb1565b5f604051808303815f87803b158015613fa5575f5ffd5b505af1158015613fb7573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b0316811580159061400257506001600160a01b03811615155b1561403e5761271061401861ffff841687615a78565b6140229190615a8f565b9250821561403e5761403e6001600160a01b0385168285613d05565b5f61404984876151b1565b9050865f036140fd575f898152601060205260409020546001600160a01b0316801580159061407757505f82115b15614090576140906001600160a01b0387168284613d05565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906140c4908d908d908b90600401615bb1565b5f604051808303815f87803b1580156140db575f5ffd5b505af11580156140ed573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115614116576141166147ce565b60405190808252806020026020018201604052801561413f578160200160208202803683370190505b5090505f61414d8984615a8f565b90505f805b8a81101561418c578284828151811061416d5761416d61517b565b602090810291909101015261418283836151c4565b9150600101614152565b505f61419882866151b1565b905080156141d55780846141ad60018e6151b1565b815181106141bd576141bd61517b565b602002602001018181516141d191906151c4565b9052505b6001546141ef906001600160a01b038b811691168761451f565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161423393929190615c11565b5f604051808303815f87803b15801561424a575f5ffd5b505af115801561425c573d5f5f3e3d5ffd5b505060015461427a92506001600160a01b038c81169250165f61451f565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516142ac929190615c46565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016142f893929190615bb1565b5f604051808303815f87803b15801561430f575f5ffd5b505af1158015614321573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561435857614358614a7f565b0361437d57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561439157614391614a7f565b036143b25760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156143c6576143c6614a7f565b036143e757604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561443057614430614a7f565b0217905550825f516020615c745f395f51905f52826006604051614455929190615462565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161368b929190615aee565b6144976145af565b611be457604051631afcd79f60e31b815260040160405180910390fd5b6136a061448f565b5f5f60205f8451602086015f885af1806144db576040513d5f823e3d81fd5b50505f513d915081156144f25780600114156144ff565b6001600160a01b0384163b155b15613b9b5783604051635274afe760e01b8152600401610bfb9190614a1b565b5f836001600160a01b031663095ea7b38484604051602401614542929190615b98565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061457b84826145c8565b613b9b576145a584856001600160a01b031663095ea7b3865f604051602401613b69929190615b98565b613b9b84826144bc565b5f6145b8613993565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614607575081156145f95780600114614607565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614639614768565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156146bc579160200282015b828111156146bc5782518255916020019190600101906146a1565b506146c8929150614786565b5090565b6001830191839082156146bc579160200282015f5b8382111561472b57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146e1565b801561475b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261472b565b50506146c8929150614786565b60405180604001604052806002906020820280368337509192915050565b5b808211156146c8575f8155600101614787565b6001600160a01b0381168114610d3f575f5ffd5b80356147b98161479a565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561480a5761480a6147ce565b604052919050565b5f6001600160401b0382111561482a5761482a6147ce565b5060051b60200190565b5f82601f830112614843575f5ffd5b81356001600160401b0381111561485c5761485c6147ce565b61486f601f8201601f19166020016147e2565b818152846020838601011115614883575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126148ae575f5ffd5b81356148c16148bc82614812565b6147e2565b8082825260208201915060208360051b8601019250858311156148e2575f5ffd5b602085015b838110156149225780356001600160401b03811115614904575f5ffd5b614913886020838a0101614834565b845250602092830192016148e7565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614944575f5ffd5b883561494f8161479a565b9750602089013561495f8161479a565b9650604089013561496f8161479a565b9550606089013561497f8161479a565b9450608089013561498f8161479a565b935060a089013592506149a58a60c08b016147be565b91506101208901356001600160401b038111156149c0575f5ffd5b6149cc8b828c0161489f565b9150509295985092959890939650565b5f602082840312156149ec575f5ffd5b8135613cfe8161479a565b5f60208284031215614a07575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147b9575f5ffd5b5f5f60408385031215614a4e575f5ffd5b614a5783614a2f565b946020939093013593505050565b5f60608284031215614a75575f5ffd5b613cfe83836147be565b634e487b7160e01b5f52602160045260245ffd5b600e8110614aa357614aa3614a7f565b9052565b602081016139b78284614a93565b60048110614aa357614aa3614a7f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614b03602082018f614ab5565b8c60408201528b6060820152614b1c608082018c614a0e565b6101c060a08201525f614b336101c083018c614ac5565b82810360c0840152614b45818c614ac5565b9050614b5460e084018b614a0e565b614b6261010084018a614a0e565b8761012084015286610140840152828103610160840152614b838187614ac5565b915050614b94610180830185614a0e565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015613b9b578151845260209384019390910190600101614bb3565b805182525f6020820151614be96020850182614ab5565b50604082015160408401526060820151614c066060850182614bb0565b50608082015160a084015260a0820151614c2360c0850182614a0e565b5060c082015161020060e0850152614c3f610200850182614ac5565b905060e0830151848203610100860152614c598282614ac5565b915050610100830151614c70610120860182614a0e565b50610120830151614c85610140860182614a0e565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614cb78282614ac5565b9150506101a0830151614cce6101c0860182614a0e565b506101c08301518015156101e0860152613c86565b602081525f613cfe6020830184614bd2565b5f60208284031215614d05575f5ffd5b81356001600160401b03811115614d1a575f5ffd5b614d2684828501614834565b949350505050565b5f60208284031215614d3e575f5ffd5b81356001600160401b03811115614d53575f5ffd5b82016101008185031215613cfe575f5ffd5b828152604060208201525f614d266040830184614bd2565b5f60208284031215614d8d575f5ffd5b81356001600160401b03811115614da2575f5ffd5b614d268482850161489f565b5f5f60408385031215614dbf575f5ffd5b823591506020830135614dd18161479a565b809150509250929050565b5f5f60408385031215614ded575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016139b7565b821515815260408101613cfe6020830184614a93565b5f5f83601f840112614e43575f5ffd5b5081356001600160401b03811115614e59575f5ffd5b602083019150836020828501011115613eb1575f5ffd5b5f5f5f5f5f60608688031215614e84575f5ffd5b8535945060208601356001600160401b03811115614ea0575f5ffd5b614eac88828901614e33565b90955093505060408601356001600160401b03811115614eca575f5ffd5b614ed688828901614e33565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614f4160e0840182614a0e565b50610100830151614f5961010084018261ffff169052565b50610120830151614f7161012084018261ffff169052565b50610140830151614f8961014084018261ffff169052565b50610160830151614fa161016084018261ffff169052565b50610180830151614fb961018084018261ffff169052565b506101a0830151614fd36101a084018263ffffffff169052565b506101c0830151614fed6101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a03121561500a575f5ffd5b8735965060208801356001600160401b03811115615026575f5ffd5b6150328a828b01614e33565b90975095505060408801356001600160401b03811115615050575f5ffd5b61505c8a828b01614e33565b90955093505060608801356001600160401b0381111561507a575f5ffd5b6150868a828b01614e33565b989b979a50959850939692959293505050565b5f5f604083850312156150aa575f5ffd5b82359150602083013560ff81168114614dd1575f5ffd5b60078110614aa357614aa3614a7f565b602081016139b782846150c1565b5f6101e08284031280156150f1575f5ffd5b509092915050565b5f5f6060838503121561510a575f5ffd5b61511383614a2f565b915083606084011115615124575f5ffd5b50926020919091019150565b600181811c9082168061514457607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215615172575f5ffd5b613cfe82614a2f565b634e487b7160e01b5f52603260045260245ffd5b602081016139b78284614ab5565b634e487b7160e01b5f52601160045260245ffd5b818103818111156139b7576139b761519d565b808201808211156139b7576139b761519d565b5f600182016151e8576151e861519d565b5060010190565b5f5f8335601e19843603018112615204575f5ffd5b8301803591506001600160401b0382111561521d575f5ffd5b602001915036819003821315613eb1575f5ffd5b8015158114610d3f575f5ffd5b5f6020828403121561524e575f5ffd5b8135613cfe81615231565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6152a060a08301888a615259565b82810360608401526152b3818789615259565b905082810360808401526152c8818587615259565b9b9a5050505050505050505050565b5f602082840312156152e7575f5ffd5b5051919050565b601f821115613d2b57805f5260205f20601f840160051c810160208510156153135750805b601f840160051c820191505b81811015615332575f815560010161531f565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615366576153666147ce565b61537a816153748454615130565b846152ee565b6020601f8211600181146153a7575f83156153955750848201515b61539f8482615339565b855550615332565b5f84815260208120601f198516915b828110156153d657878501518255602094850194600190920191016153b6565b50848210156153f357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561543c57815163ffffffff16835260209283019290910190600101615417565b505050949350505050565b5f60208284031215615457575f5ffd5b8151613cfe81615231565b6040810161547082856150c1565b613cfe60208301846150c1565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156154ea57603f198786030184526154d5858351614ac5565b945060209384019391909101906001016154b9565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161553b60208301856150c1565b614d2660408301846150c1565b5f8151808452602084019350602083015f5b828110156155815781516001600160a01b031686526020958601959091019060010161555a565b5093949350505050565b848152836020820152608060408201525f6155a96080830185615548565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f614607606083018486615259565b602081525f614d26602083018486615259565b6001600160401b0383111561561a5761561a6147ce565b61562e836156288354615130565b836152ee565b5f601f84116001811461565a575f85156156485750838201355b6156528682615339565b845550615332565b5f83815260208120601f198716915b828110156156895786850135825560209485019460019092019101615669565b50868210156156a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6156d0606083018688615259565b82810360408401526156e3818587615259565b98975050505050505050565b604081525f615702604083018688615259565b8281036020840152615715818587615259565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356147b981615720565b5f6020828403121561574a575f5ffd5b8135613cfe81615720565b63ffffffff81168114610d3f575f5ffd5b80356147b981615755565b5f60208284031215615781575f5ffd5b8135613cfe81615755565b5f81356139b78161479a565b5f81356139b781615720565b5f81356139b781615755565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161582061580360e0850161578c565b82546001600160a01b0319166001600160a01b0391909116178255565b6158506158306101008501615798565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6158806158606101208501615798565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6158b06158906101408501615798565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6158e06158c06101608501615798565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6159106158f06101808501615798565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161593c6159256101a085016157a4565b825463ffffffff191663ffffffff91909116178255565b613d2b61594c6101c085016157a4565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016159bf60e084016147ae565b6159cc60e0840182614a0e565b506159da610100840161572f565b61ffff166101008301526159f1610120840161572f565b61ffff16610120830152615a08610140840161572f565b61ffff16610140830152615a1f610160840161572f565b61ffff16610160830152615a36610180840161572f565b61ffff16610180830152615a4d6101a08401615766565b63ffffffff166101a0830152615a666101c08401615766565b63ffffffff81166101c0840152614fed565b80820281158282048414176139b7576139b761519d565b5f82615aa957634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b6002811015615ae5578135615aca81615755565b63ffffffff1683526020928301929190910190600101615ab6565b50505092915050565b60408101615afc82856150c1565b613cfe6020830184614a93565b5f60208284031215615b19575f5ffd5b81516001600160401b03811115615b2e575f5ffd5b8201601f81018413615b3e575f5ffd5b8051615b4c6148bc82614812565b8082825260208201915060208360051b850101925086831115615b6d575f5ffd5b6020840193505b82841015614607578351615b878161479a565b825260209384019390910190615b74565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615bc96060830185615548565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615581578151865260209586019590910190600101615bf3565b6001600160a01b03841681526060602082018190525f90615c3490830185615548565b82810360408401526146078185615be1565b604081525f615c586040830185615548565b8281036020840152615c6a8185615be1565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461492c565b61095a565b005b6102f06103003660046149dc565b610ba1565b61032d6103133660046149f7565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614a1b565b60405180910390f35b61032d6103513660046149f7565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614a3d565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046149dc565b610c89565b6102f06103b4366004614a65565b610d2e565b6103db6103c73660046149f7565b5f908152600f602052604090205460ff1690565b60405161033a9190614aa7565b6103fb6103f63660046149f7565b610d42565b60405161033a9e9d9c9b9a99989796959493929190614af3565b6104286104233660046149f7565b610f6c565b60405161033a9190614ce3565b6104546104433660046149f7565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614cf5565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046149f7565b611269565b6102f06104c13660046149dc565b6112f8565b6104d96104d4366004614d2e565b61138b565b60405161033a929190614d65565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614d7d565b611be6565b6102f061052c366004614dae565b611c7e565b6102f061053f3660046149f7565b611d07565b6102f0610552366004614ddc565b611e05565b60015461032d906001600160a01b031681565b61032d611ef8565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f26565b60405161033a9190614dfc565b6102f06105ba3660046149f7565b611f6c565b61059f6105cd3660046149f7565b612114565b6105e56105e03660046149f7565b61216d565b60405161033a929190614e1d565b61032d6106013660046149f7565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614e70565b612194565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ee7565b61032d61078e3660046149f7565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614ff4565b61242c565b6102f06107c9366004614d7d565b61265c565b6102f06107dc366004615099565b6126f3565b6102f06107ef3660046149dc565b6127de565b6102f0610802366004614ddc565b612885565b6104906108153660046149dc565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614dae565b612968565b6102f06108533660046149f7565b612a1b565b61087a6108663660046149f7565b5f908152600d602052604090205460ff1690565b60405161033a91906150d1565b6102f06108953660046150df565b612a58565b6104546108a8366004614d2e565b612dae565b6102f06108bb3660046149dc565b613332565b6102f06108ce3660046150f9565b6133cc565b60025461032d906001600160a01b031681565b6102f06108f43660046149dc565b613698565b6103db6109073660046149f7565b6136d2565b6102f061091a3660046149dc565b61386c565b61032d61092d3660046149f7565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046149dc565b613904565b5f610963613993565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a03336139bd565b610a0c88612a1b565b610a158c61386c565b610a1e8b613332565b610a278a610ba1565b610a3089610c89565b610a39876139ce565b610a428661265c565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611ef8565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613698565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613b02565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613b02565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb9190614a1b565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d23908390614a1b565b60405180910390a150565b610d36613b02565b610d3f816139ce565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990615130565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590615130565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90615130565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614611565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614a7f565b6003811115610fc257610fc2614a7f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490615130565b80601f016020809104026020016040519081016040528092919081815260200182805461106090615130565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490615130565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090615130565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90615130565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890615130565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613b02565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613b02565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d23908390614a1b565b5f611394614611565b5f6012816113a56020870187615162565b60038111156113b6576113b6614a7f565b60038111156113c7576113c7614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f816001600281106114455761144561517b565b602002015163ffffffff1611845f0160208101906114639190615162565b906114825760405163286c068d60e11b8152600401610bfb919061518f565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f24260408901356151b1565b6114fc91906151c4565b61150691906151c4565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016149dc565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016149dc565b9061158e5760405163295a6a6f60e11b8152600401610bfb9190614a1b565b505f61159986612dae565b60068054965090915085905f6115ae836151d7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff19166001179055601090945282902080543394169390931790925560165491925061168991908901356151c4565b5f878152600e60209081526040909120600101919091558186526116af90880188615162565b856020019060038111156116c5576116c5614a7f565b908160038111156116d8576116d8614a7f565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016149dc565b6001600160a01b031660a086015261173b60808801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c080870191909152611783908801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d090610100890190890161523e565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613b34565b5f6118316080890160608a016149dc565b6001600160a01b031663fefd9a8b888461184e60808d018d6151ef565b61185b60a08f018f6151ef565b8f8060c0019061186b91906151ef565b6040518963ffffffff1660e01b815260040161188e989796959493929190615281565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906152d7565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614a7f565b0217905550604082015181600201556060820151816003019060026119c892919061468e565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d908261534d565b5060e08201516008820190611a22908261534d565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a908261534d565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615402565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b309190615447565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016149dc565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614d65565b60405180910390a2885f516020615c745f395f51905f525f6001604051611bbf929190615462565b60405180910390a250505050505050915091565b611bdb613b02565b611be45f613ba1565b565b611bee613b02565b80515f5b81811015611c4257600b838281518110611c0e57611c0e61517b565b6020026020010151604051611c23919061547d565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615493565b60405180910390a15050565b611c86613b02565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d305760405162461bcd60e51b8152600401610bfb906154f6565b5f818152600d602052604090205460ff166001816006811115611d5557611d55614a7f565b14611d7a57816001826040516337e1404160e01b8152600401610bfb93929190615527565b5f828152600d60205260409020805460ff19166002179055601554611d9f90426151c4565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615c745f395f51905f5260016002604051611df9929190615462565b60405180910390a25050565b5f546001600160a01b03163314611e2e5760405162461bcd60e51b8152600401610bfb906154f6565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e5e57611e5e614a7f565b14611e8357836002826040516337e1404160e01b8152600401610bfb93929190615527565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615c745f395f51905f5260026003604051611eea929190615462565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9157611f91614a7f565b14611fce5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610bfb565b5f828152600c6020526040902054806120205760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610bfb565b5f838152600c6020526040812081905561203984613c11565b5f858152601160205260409020546002549192506001600160a01b03908116916120669183911685613d05565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061209c90889087908790879060040161558b565b5f604051808303815f87803b1580156120b3575f5ffd5b505af11580156120c5573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612105929190918252602082015260400190565b60405180910390a25050505050565b61213560405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661218a8482613d30565b9250925050915091565b5f5f61219f87610f6c565b5f888152600d602052604090205490915060ff1660038160068111156121c7576121c7614a7f565b14886003839091926121ef576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015612253576040516308f3034360e31b815260048101929092526024820152604401610bfb565b505060608301516020015189904281111561228a5760405163017e35e560e71b815260048101929092526024820152604401610bfb565b50506101608301518990156122b557604051637eb9cea960e11b8152600401610bfb91815260200190565b505f88886040516122c79291906155c2565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560175490915061230990426151c4565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90612356908d9085908c908c906004016155d1565b6020604051808303815f875af1158015612372573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123969190615447565b94508888866123ba57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123ee9291906155f0565b60405180910390a2895f516020615c745f395f51905f5260036004604051612417929190615462565b60405180910390a25050505095945050505050565b5f5f61243789610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561245f5761245f614a7f565b148a600483909192612487576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124ea576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016125078a8c83615603565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161254b9291906155c2565b6040519081900381206001600160e01b031960e084901b168252612579918c908c908c908c906004016156b7565b602060405180830381865afa158015612594573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125b89190615447565b93508989856125dc57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b50506125e78b613eb8565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161261d94939291906156ef565b60405180910390a28a5f516020615c745f395f51905f5260046005604051612646929190615462565b60405180910390a2505050979650505050505050565b612664613b02565b80515f5b818110156126c3576001600b8483815181106126865761268661517b565b602002602001015160405161269b919061547d565b908152604051908190036020019020805491151560ff19909216919091179055600101612668565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615493565b5f546001600160a01b031633148061271557506003546001600160a01b031633145b6127615760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610bfb565b5f8160ff161180156127775750600d60ff821611155b6127bc5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b6127da828260ff16600d8111156127d5576127d5614a7f565b614334565b5050565b6127e6613b02565b6001600160a01b03811661283c5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610bfb565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612920575f5ffd5b505af1158015612932573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611df991815260200190565b612970613b02565b6001600160a01b038116158015906129a157505f828152600960205260409020546001600160a01b03828116911614155b82906129c3576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612a23613b02565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b612a60613b02565b612710612a756101208301610100840161573a565b61ffff161115612abd5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610bfb565b612710612ad26101408301610120840161573a565b61ffff161115612b195760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610bfb565b612710612b2e6101608301610140840161573a565b61ffff161115612b805760405162461bcd60e51b815260206004820152601c60248201527f444b47207574696c697a6174696f6e20657863656564732031303025000000006044820152606401610bfb565b612710612b956101808301610160840161573a565b61ffff161115612be75760405162461bcd60e51b815260206004820181905260248201527f436f6d70757465207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612710612bfc6101a08301610180840161573a565b61ffff161115612c4e5760405162461bcd60e51b815260206004820181905260248201527f44656372797074207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612c606101408201610120830161573a565b61ffff161580612c8957505f612c7d610100830160e084016149dc565b6001600160a01b031614155b612ce75760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610bfb565b612cf96101e082016101c08301615771565b63ffffffff16612d116101c083016101a08401615771565b63ffffffff161015612d6f5760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610bfb565b806018612d7c82826157b0565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d23919061596e565b5f80601281612dc06020860186615162565b6003811115612dd157612dd1614a7f565b6003811115612de257612de2614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612e09579050505050505090505f81600160028110612e6057612e6061517b565b602002015163ffffffff1611835f016020810190612e7e9190615162565b90612e9d5760405163286c068d60e11b8152600401610bfb919061518f565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612fc8576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612fa79190615162565b90612fc65760405163010b971d60e31b8152600401610bfb919061518f565b505b6101c081015163ffffffff1615613017576101c081015184519063ffffffff908116908216101561301557604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b604086013560208701358110156130445760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f91612710916130629161ffff1690615a78565b61306c9190615a8f565b61271061ffff1683610160015161ffff1660156001015461308d9190615a78565b6130979190615a8f565b61271061ffff1684610140015161ffff1660155f01546130b79190615a78565b6130c19190615a8f565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa15801561310d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313191906152d7565b61313b91906151c4565b61314591906151b1565b61314f91906151c4565b61315991906151c4565b61316391906151c4565b90505f6131716001866151b1565b61317c906002615a78565b613187906002615a78565b6131929060066151c4565b90505f85845f01516131a49190615a78565b9050818685602001516131b79190615a78565b6131c19190615a78565b6131cb90826151c4565b905060018611156132135760026131e36001886151b1565b6131ed9088615a78565b85604001516131fc9190615a78565b6132069190615a8f565b61321090826151c4565b90505b81868560c001516132249190615a78565b61322e9190615a78565b61323890826151c4565b90508286856060015161324b9190615a78565b6132559190615a78565b61325f90826151c4565b90508484608001516132719190615a78565b61327b90826151c4565b905060018511156132c35760026132936001876151b1565b61329d9087615a78565b85604001516132ac9190615a78565b6132b69190615a8f565b6132c090826151c4565b90505b60a08401516132d290826151c4565b610100850151909150612710906132ed9061ffff16826151c4565b6132f79083615a78565b6133019190615a8f565b9750878061332557604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b61333a613b02565b6001600160a01b0381161580159061336057506001546001600160a01b03828116911614155b8190613380576040516320252f0b60e01b8152600401610bfb9190614a1b565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d23908390614a1b565b6133d4613b02565b6133e16020820182615771565b63ffffffff166133f76040830160208401615771565b63ffffffff161015801561341c57505f6134146020830183615771565b63ffffffff16115b61345c5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610bfb565b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215613594576101a081015163ffffffff166135456040840160208501615771565b63ffffffff1610156135945760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610bfb565b6101c081015163ffffffff1615613608576101c081015163ffffffff166135be6020840184615771565b63ffffffff1610156136085760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610bfb565b8160125f85600381111561361e5761361e614a7f565b600381111561362f5761362f614a7f565b815260208101919091526040015f206136499160026146cc565b5082600381111561365c5761365c614a7f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161368b9190615aae565b60405180910390a2505050565b6136a0613b02565b6001600160a01b0381166136c9575f604051631e4fbdf760e01b8152600401610bfb9190614a1b565b610d3f81613ba1565b5f818152600d602052604081205460ff16818160068111156136f6576136f6614a7f565b0361371b57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561372f5761372f614a7f565b036137505760405163462c7bed60e01b815260048101849052602401610bfb565b600681600681111561376457613764614a7f565b0361378557604051633de16e3560e11b815260048101849052602401610bfb565b5f6137908483613d30565b93509050806137b557604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156137fe576137fe614a7f565b0217905550835f516020615c745f395f51905f52836006604051613823929190615462565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161385d929190615aee565b60405180910390a25050919050565b613874613b02565b6001600160a01b0381161580159061389957505f546001600160a01b03828116911614155b81906138b9576040516375ac4eb760e11b8152600401610bfb9190614a1b565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d23908390614a1b565b6001600160a01b0381165f90815260076020526040902054819060ff16156139405760405163b29d459560e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d23908390614a1b565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6139c561448f565b610d3f816144b4565b8035613a115760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610bfb565b5f816020013511613a5d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610bfb565b5f816040013511613aac5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610bfb565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b33613b0b611ef8565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb9190614a1b565b6040516001600160a01b038481166024830152838116604483015260648201839052613b9b9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506144bc565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613c3957613c39614a7f565b1480613c565750600281600d811115613c5457613c54614a7f565b145b15613c8e575f5b604051908082528060200260200182016040528015613c86578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613cf457506040513d5f823e601f3d908101601f19168201604052613cf19190810190615b09565b60015b613cfe575f613c5d565b9392505050565b613d2b83846001600160a01b031663a9059cbb8585604051602401613b69929190615b98565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613daa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dce91906152d7565b90506001856006811115613de457613de4614a7f565b148015613df057508042115b15613e0357600180935093505050613eb1565b6002856006811115613e1757613e17614a7f565b148015613e245750815142115b15613e385760016003935093505050613eb1565b6003856006811115613e4c57613e4c614a7f565b148015613e5c5750816020015142115b15613e705760016006935093505050613eb1565b6004856006811115613e8457613e84614a7f565b148015613e945750816040015142115b15613ea8576001600a935093505050613eb1565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613efd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613f249190810190615b09565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613fc2576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613f8e90889088908690600401615bb1565b5f604051808303815f87803b158015613fa5575f5ffd5b505af1158015613fb7573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b0316811580159061400257506001600160a01b03811615155b1561403e5761271061401861ffff841687615a78565b6140229190615a8f565b9250821561403e5761403e6001600160a01b0385168285613d05565b5f61404984876151b1565b9050865f036140fd575f898152601060205260409020546001600160a01b0316801580159061407757505f82115b15614090576140906001600160a01b0387168284613d05565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906140c4908d908d908b90600401615bb1565b5f604051808303815f87803b1580156140db575f5ffd5b505af11580156140ed573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115614116576141166147ce565b60405190808252806020026020018201604052801561413f578160200160208202803683370190505b5090505f61414d8984615a8f565b90505f805b8a81101561418c578284828151811061416d5761416d61517b565b602090810291909101015261418283836151c4565b9150600101614152565b505f61419882866151b1565b905080156141d55780846141ad60018e6151b1565b815181106141bd576141bd61517b565b602002602001018181516141d191906151c4565b9052505b6001546141ef906001600160a01b038b811691168761451f565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161423393929190615c11565b5f604051808303815f87803b15801561424a575f5ffd5b505af115801561425c573d5f5f3e3d5ffd5b505060015461427a92506001600160a01b038c81169250165f61451f565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516142ac929190615c46565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016142f893929190615bb1565b5f604051808303815f87803b15801561430f575f5ffd5b505af1158015614321573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561435857614358614a7f565b0361437d57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561439157614391614a7f565b036143b25760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156143c6576143c6614a7f565b036143e757604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561443057614430614a7f565b0217905550825f516020615c745f395f51905f52826006604051614455929190615462565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161368b929190615aee565b6144976145af565b611be457604051631afcd79f60e31b815260040160405180910390fd5b6136a061448f565b5f5f60205f8451602086015f885af1806144db576040513d5f823e3d81fd5b50505f513d915081156144f25780600114156144ff565b6001600160a01b0384163b155b15613b9b5783604051635274afe760e01b8152600401610bfb9190614a1b565b5f836001600160a01b031663095ea7b38484604051602401614542929190615b98565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061457b84826145c8565b613b9b576145a584856001600160a01b031663095ea7b3865f604051602401613b69929190615b98565b613b9b84826144bc565b5f6145b8613993565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614607575081156145f95780600114614607565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614639614768565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156146bc579160200282015b828111156146bc5782518255916020019190600101906146a1565b506146c8929150614786565b5090565b6001830191839082156146bc579160200282015f5b8382111561472b57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146e1565b801561475b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261472b565b50506146c8929150614786565b60405180604001604052806002906020820280368337509192915050565b5b808211156146c8575f8155600101614787565b6001600160a01b0381168114610d3f575f5ffd5b80356147b98161479a565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561480a5761480a6147ce565b604052919050565b5f6001600160401b0382111561482a5761482a6147ce565b5060051b60200190565b5f82601f830112614843575f5ffd5b81356001600160401b0381111561485c5761485c6147ce565b61486f601f8201601f19166020016147e2565b818152846020838601011115614883575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126148ae575f5ffd5b81356148c16148bc82614812565b6147e2565b8082825260208201915060208360051b8601019250858311156148e2575f5ffd5b602085015b838110156149225780356001600160401b03811115614904575f5ffd5b614913886020838a0101614834565b845250602092830192016148e7565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614944575f5ffd5b883561494f8161479a565b9750602089013561495f8161479a565b9650604089013561496f8161479a565b9550606089013561497f8161479a565b9450608089013561498f8161479a565b935060a089013592506149a58a60c08b016147be565b91506101208901356001600160401b038111156149c0575f5ffd5b6149cc8b828c0161489f565b9150509295985092959890939650565b5f602082840312156149ec575f5ffd5b8135613cfe8161479a565b5f60208284031215614a07575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147b9575f5ffd5b5f5f60408385031215614a4e575f5ffd5b614a5783614a2f565b946020939093013593505050565b5f60608284031215614a75575f5ffd5b613cfe83836147be565b634e487b7160e01b5f52602160045260245ffd5b600e8110614aa357614aa3614a7f565b9052565b602081016139b78284614a93565b60048110614aa357614aa3614a7f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614b03602082018f614ab5565b8c60408201528b6060820152614b1c608082018c614a0e565b6101c060a08201525f614b336101c083018c614ac5565b82810360c0840152614b45818c614ac5565b9050614b5460e084018b614a0e565b614b6261010084018a614a0e565b8761012084015286610140840152828103610160840152614b838187614ac5565b915050614b94610180830185614a0e565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015613b9b578151845260209384019390910190600101614bb3565b805182525f6020820151614be96020850182614ab5565b50604082015160408401526060820151614c066060850182614bb0565b50608082015160a084015260a0820151614c2360c0850182614a0e565b5060c082015161020060e0850152614c3f610200850182614ac5565b905060e0830151848203610100860152614c598282614ac5565b915050610100830151614c70610120860182614a0e565b50610120830151614c85610140860182614a0e565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614cb78282614ac5565b9150506101a0830151614cce6101c0860182614a0e565b506101c08301518015156101e0860152613c86565b602081525f613cfe6020830184614bd2565b5f60208284031215614d05575f5ffd5b81356001600160401b03811115614d1a575f5ffd5b614d2684828501614834565b949350505050565b5f60208284031215614d3e575f5ffd5b81356001600160401b03811115614d53575f5ffd5b82016101008185031215613cfe575f5ffd5b828152604060208201525f614d266040830184614bd2565b5f60208284031215614d8d575f5ffd5b81356001600160401b03811115614da2575f5ffd5b614d268482850161489f565b5f5f60408385031215614dbf575f5ffd5b823591506020830135614dd18161479a565b809150509250929050565b5f5f60408385031215614ded575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016139b7565b821515815260408101613cfe6020830184614a93565b5f5f83601f840112614e43575f5ffd5b5081356001600160401b03811115614e59575f5ffd5b602083019150836020828501011115613eb1575f5ffd5b5f5f5f5f5f60608688031215614e84575f5ffd5b8535945060208601356001600160401b03811115614ea0575f5ffd5b614eac88828901614e33565b90955093505060408601356001600160401b03811115614eca575f5ffd5b614ed688828901614e33565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614f4160e0840182614a0e565b50610100830151614f5961010084018261ffff169052565b50610120830151614f7161012084018261ffff169052565b50610140830151614f8961014084018261ffff169052565b50610160830151614fa161016084018261ffff169052565b50610180830151614fb961018084018261ffff169052565b506101a0830151614fd36101a084018263ffffffff169052565b506101c0830151614fed6101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a03121561500a575f5ffd5b8735965060208801356001600160401b03811115615026575f5ffd5b6150328a828b01614e33565b90975095505060408801356001600160401b03811115615050575f5ffd5b61505c8a828b01614e33565b90955093505060608801356001600160401b0381111561507a575f5ffd5b6150868a828b01614e33565b989b979a50959850939692959293505050565b5f5f604083850312156150aa575f5ffd5b82359150602083013560ff81168114614dd1575f5ffd5b60078110614aa357614aa3614a7f565b602081016139b782846150c1565b5f6101e08284031280156150f1575f5ffd5b509092915050565b5f5f6060838503121561510a575f5ffd5b61511383614a2f565b915083606084011115615124575f5ffd5b50926020919091019150565b600181811c9082168061514457607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215615172575f5ffd5b613cfe82614a2f565b634e487b7160e01b5f52603260045260245ffd5b602081016139b78284614ab5565b634e487b7160e01b5f52601160045260245ffd5b818103818111156139b7576139b761519d565b808201808211156139b7576139b761519d565b5f600182016151e8576151e861519d565b5060010190565b5f5f8335601e19843603018112615204575f5ffd5b8301803591506001600160401b0382111561521d575f5ffd5b602001915036819003821315613eb1575f5ffd5b8015158114610d3f575f5ffd5b5f6020828403121561524e575f5ffd5b8135613cfe81615231565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6152a060a08301888a615259565b82810360608401526152b3818789615259565b905082810360808401526152c8818587615259565b9b9a5050505050505050505050565b5f602082840312156152e7575f5ffd5b5051919050565b601f821115613d2b57805f5260205f20601f840160051c810160208510156153135750805b601f840160051c820191505b81811015615332575f815560010161531f565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615366576153666147ce565b61537a816153748454615130565b846152ee565b6020601f8211600181146153a7575f83156153955750848201515b61539f8482615339565b855550615332565b5f84815260208120601f198516915b828110156153d657878501518255602094850194600190920191016153b6565b50848210156153f357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561543c57815163ffffffff16835260209283019290910190600101615417565b505050949350505050565b5f60208284031215615457575f5ffd5b8151613cfe81615231565b6040810161547082856150c1565b613cfe60208301846150c1565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156154ea57603f198786030184526154d5858351614ac5565b945060209384019391909101906001016154b9565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161553b60208301856150c1565b614d2660408301846150c1565b5f8151808452602084019350602083015f5b828110156155815781516001600160a01b031686526020958601959091019060010161555a565b5093949350505050565b848152836020820152608060408201525f6155a96080830185615548565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f614607606083018486615259565b602081525f614d26602083018486615259565b6001600160401b0383111561561a5761561a6147ce565b61562e836156288354615130565b836152ee565b5f601f84116001811461565a575f85156156485750838201355b6156528682615339565b845550615332565b5f83815260208120601f198716915b828110156156895786850135825560209485019460019092019101615669565b50868210156156a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6156d0606083018688615259565b82810360408401526156e3818587615259565b98975050505050505050565b604081525f615702604083018688615259565b8281036020840152615715818587615259565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356147b981615720565b5f6020828403121561574a575f5ffd5b8135613cfe81615720565b63ffffffff81168114610d3f575f5ffd5b80356147b981615755565b5f60208284031215615781575f5ffd5b8135613cfe81615755565b5f81356139b78161479a565b5f81356139b781615720565b5f81356139b781615755565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161582061580360e0850161578c565b82546001600160a01b0319166001600160a01b0391909116178255565b6158506158306101008501615798565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6158806158606101208501615798565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6158b06158906101408501615798565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6158e06158c06101608501615798565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6159106158f06101808501615798565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161593c6159256101a085016157a4565b825463ffffffff191663ffffffff91909116178255565b613d2b61594c6101c085016157a4565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016159bf60e084016147ae565b6159cc60e0840182614a0e565b506159da610100840161572f565b61ffff166101008301526159f1610120840161572f565b61ffff16610120830152615a08610140840161572f565b61ffff16610140830152615a1f610160840161572f565b61ffff16610160830152615a36610180840161572f565b61ffff16610180830152615a4d6101a08401615766565b63ffffffff166101a0830152615a666101c08401615766565b63ffffffff81166101c0840152614fed565b80820281158282048414176139b7576139b761519d565b5f82615aa957634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b6002811015615ae5578135615aca81615755565b63ffffffff1683526020928301929190910190600101615ab6565b50505092915050565b60408101615afc82856150c1565b613cfe6020830184614a93565b5f60208284031215615b19575f5ffd5b81516001600160401b03811115615b2e575f5ffd5b8201601f81018413615b3e575f5ffd5b8051615b4c6148bc82614812565b8082825260208201915060208360051b850101925086831115615b6d575f5ffd5b6020840193505b82841015614607578351615b878161479a565b825260209384019390910190615b74565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615bc96060830185615548565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615581578151865260209586019590910190600101615bf3565b6001600160a01b03841681526060602082018190525f90615c3490830185615548565b82810360408401526146078185615be1565b604081525f615c586040830185615548565b8281036020840152615c6a8185615be1565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 01a3a8bfc5..b504fc1c46 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index cc3653cbab..c5ca800a4b 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -755,6 +755,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "sortitionSubmissionWindow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -793,5 +806,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index 814d2f3f39..cc7dba9dbd 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -498,6 +498,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -1032,6 +1047,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -1568,6 +1598,21 @@ "name": "protocolShareBps", "type": "uint16" }, + { + "internalType": "uint16", + "name": "dkgUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "computeUtilizationBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "decryptUtilizationBps", + "type": "uint16" + }, { "internalType": "uint32", "name": "minCommitteeSize", @@ -1626,5 +1671,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 4360695441..3fb31bd749 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index d92ac1c39f..a47fa2dfe4 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1309,5 +1309,5 @@ }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-7be5abc9893f8994323749f03d05435db17c1751" + "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index c54c8e7ff6..0e8ebfc57a 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -310,6 +310,9 @@ contract Enclave is IEnclave, OwnableUpgradeable { protocolTreasury: address(0), marginBps: 1000, // 10% protocolShareBps: 0, + dkgUtilizationBps: 2500, // 25% — typical DKG completes in ~25% of window + computeUtilizationBps: 5000, // 50% — compute has moderate variance + decryptUtilizationBps: 2500, // 25% — decryption is fast when nodes cooperate minCommitteeSize: 0, minThreshold: 0 }); @@ -1078,6 +1081,18 @@ contract Enclave is IEnclave, OwnableUpgradeable { function setPricingConfig(PricingConfig calldata config) public onlyOwner { require(config.marginBps <= BPS_BASE, "Margin exceeds 100%"); require(config.protocolShareBps <= BPS_BASE, "Share exceeds 100%"); + require( + config.dkgUtilizationBps <= BPS_BASE, + "DKG utilization exceeds 100%" + ); + require( + config.computeUtilizationBps <= BPS_BASE, + "Compute utilization exceeds 100%" + ); + require( + config.decryptUtilizationBps <= BPS_BASE, + "Decrypt utilization exceeds 100%" + ); require( config.protocolShareBps == 0 || config.protocolTreasury != address(0), @@ -1137,12 +1152,19 @@ contract Enclave is IEnclave, OwnableUpgradeable { InvalidInputDeadlineEnd(requestParams.inputWindow[1]) ); - // Duration covers the full availability period - uint256 duration = requestParams.inputWindow[1] - + // Duration covers the full availability period, using expected-case + // utilization fractions for protocol-controlled timeout windows. + // sortitionSubmissionWindow is included — CNs are locked during this phase. + uint256 duration = ciphernodeRegistry.sortitionSubmissionWindow() + + requestParams.inputWindow[1] - requestParams.inputWindow[0] + - _timeoutConfig.dkgWindow + - _timeoutConfig.computeWindow + - _timeoutConfig.decryptionWindow; + (_timeoutConfig.dkgWindow * uint256(pc.dkgUtilizationBps)) / + uint256(BPS_BASE) + + (_timeoutConfig.computeWindow * uint256(pc.computeUtilizationBps)) / + uint256(BPS_BASE) + + (_timeoutConfig.decryptionWindow * + uint256(pc.decryptUtilizationBps)) / + uint256(BPS_BASE); // ZK proof count per node: 6 fixed + 2 × (N-1) × L_dkg scaling // TODO: get dkgModuliCount from E3 params instead of hardcoding diff --git a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol index a2d59c78fc..34a113d6ba 100644 --- a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol @@ -258,6 +258,10 @@ interface ICiphernodeRegistry { /// @param _bondingRegistry Address of the bonding registry contract function setBondingRegistry(IBondingRegistry _bondingRegistry) external; + /// @notice Returns the current sortition submission window. + /// @return The sortition submission window in seconds. + function sortitionSubmissionWindow() external view returns (uint256); + /// @notice This function should be called to set the submission window for the E3 sortition. /// @param _sortitionSubmissionWindow The submission window for the E3 sortition in seconds. function setSortitionSubmissionWindow( diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index 67086b2f58..6ea4b4fd52 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -89,6 +89,9 @@ interface IEnclave { address protocolTreasury; uint16 marginBps; uint16 protocolShareBps; + uint16 dkgUtilizationBps; + uint16 computeUtilizationBps; + uint16 decryptUtilizationBps; uint32 minCommitteeSize; uint32 minThreshold; } diff --git a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol index c7fe477c34..6ba01456b8 100644 --- a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol @@ -110,6 +110,10 @@ contract MockCiphernodeRegistry is ICiphernodeRegistry { return true; } + function sortitionSubmissionWindow() external pure returns (uint256) { + return 0; + } + // solhint-disable-next-line no-empty-blocks function setSortitionSubmissionWindow(uint256) external pure {} @@ -241,6 +245,10 @@ contract MockCiphernodeRegistryEmptyKey is ICiphernodeRegistry { // solhint-disable-next-line no-empty-blocks function setBondingRegistry(IBondingRegistry) external pure {} + function sortitionSubmissionWindow() external pure returns (uint256) { + return 0; + } + // solhint-disable-next-line no-empty-blocks function setSortitionSubmissionWindow(uint256) external pure {} diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index 1628d41899..c0051a6486 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -247,6 +247,9 @@ export const deployEnclave = async ( protocolTreasury: protocolTreasury, marginBps: 1000, // 10% protocolShareBps: 2000, // 20% + dkgUtilizationBps: 2500, // 25% + computeUtilizationBps: 5000, // 50% + decryptUtilizationBps: 2500, // 25% minCommitteeSize: 0, minThreshold: 0, }); diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index 554d68cda4..518244d560 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -56,6 +56,9 @@ describe("E3 Pricing", function () { protocolTreasury: ethers.ZeroAddress, marginBps: 1000, protocolShareBps: 0, + dkgUtilizationBps: 2500, + computeUtilizationBps: 5000, + decryptUtilizationBps: 2500, minCommitteeSize: 0, minThreshold: 0, }; @@ -72,6 +75,9 @@ describe("E3 Pricing", function () { protocolTreasury: pc.protocolTreasury, marginBps: pc.marginBps, protocolShareBps: pc.protocolShareBps, + dkgUtilizationBps: pc.dkgUtilizationBps, + computeUtilizationBps: pc.computeUtilizationBps, + decryptUtilizationBps: pc.decryptUtilizationBps, minCommitteeSize: pc.minCommitteeSize, minThreshold: pc.minThreshold, }); @@ -138,7 +144,7 @@ describe("E3 Pricing", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(e3Id); const proof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(e3Id, nodes, publicKey, proof); + await registry.publishCommittee(e3Id, nodes, publicKey, proof, "0x"); }; const setup = async () => { @@ -368,22 +374,26 @@ describe("E3 Pricing", function () { }); it("computes fee correctly using the parametric formula", async function () { - const { enclave, request } = await loadFixture(setup); + const { enclave, request, ciphernodeRegistryContract } = + await loadFixture(setup); // Get the resolved threshold for Micro (committeeSize = 0) → [1, 3] const n = 3n; // total committee const m = 1n; // quorum + // Get pricing config + const pc = await enclave.getPricingConfig(); + // Get timeout config const config = await enclave.getTimeoutConfig(); + const sortitionWindow = + await ciphernodeRegistryContract.sortitionSubmissionWindow(); const duration = + sortitionWindow + BigInt(request.inputWindow[1] - request.inputWindow[0]) + - config.dkgWindow + - config.computeWindow + - config.decryptionWindow; - - // Get pricing config - const pc = await enclave.getPricingConfig(); + (config.dkgWindow * BigInt(pc.dkgUtilizationBps)) / 10000n + + (config.computeWindow * BigInt(pc.computeUtilizationBps)) / 10000n + + (config.decryptionWindow * BigInt(pc.decryptUtilizationBps)) / 10000n; // Calculate expected fee (proof-aware) const proofsPerNode = 6n + 2n * (n - 1n) * 2n; @@ -759,6 +769,9 @@ describe("E3 Pricing", function () { expect(pc.verificationPerProof).to.equal(2000); expect(pc.marginBps).to.equal(1000); expect(pc.protocolShareBps).to.equal(0); + expect(pc.dkgUtilizationBps).to.equal(2500); + expect(pc.computeUtilizationBps).to.equal(5000); + expect(pc.decryptUtilizationBps).to.equal(2500); expect(pc.protocolTreasury).to.equal(ethers.ZeroAddress); expect(pc.minCommitteeSize).to.equal(0); expect(pc.minThreshold).to.equal(0); From f03f1d9fbe241994d06ed6dfa34084413b86c993 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Fri, 27 Mar 2026 11:40:56 +0500 Subject: [PATCH 11/11] fix: review comments --- .../contracts/Enclave.sol/Enclave.json | 117 ++++- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 150 ++++++- .../interfaces/IEnclave.sol/IEnclave.json | 424 +++++++++++++++++- .../ISlashingManager.json | 2 +- .../CiphernodeRegistryOwnable.json | 2 +- .../EnclaveTicketToken.json | 2 +- .../enclave-contracts/contracts/Enclave.sol | 175 ++------ .../interfaces/ICiphernodeRegistry.sol | 91 ++++ .../contracts/interfaces/IEnclave.sol | 153 +++++++ .../registry/CiphernodeRegistryOwnable.sol | 85 ---- .../contracts/test/MockCiphernodeRegistry.sol | 2 - .../test/E3Lifecycle/E3Integration.spec.ts | 10 +- .../test/Pricing/Pricing.spec.ts | 10 +- 14 files changed, 985 insertions(+), 240 deletions(-) diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index b1a6ff8a9f..9ea44ab9b2 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -8,6 +8,49 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimum", + "type": "uint256" + } + ], + "name": "BelowMinCommitteeSize", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimum", + "type": "uint256" + } + ], + "name": "BelowMinThreshold", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "BpsExceedsMax", + "type": "error" + }, { "inputs": [ { @@ -106,6 +149,17 @@ "name": "E3DoesNotExist", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "E3NotFailed", + "type": "error" + }, { "inputs": [ { @@ -269,6 +323,21 @@ "name": "InvalidStage", "type": "error" }, + { + "inputs": [], + "name": "InvalidThresholdValues", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTimeoutWindow", + "type": "error" + }, + { + "inputs": [], + "name": "MinSizeBelowMinThreshold", + "type": "error" + }, { "inputs": [ { @@ -291,11 +360,37 @@ "name": "ModuleNotEnabled", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "NoPaymentToRefund", + "type": "error" + }, { "inputs": [], "name": "NotInitializing", "type": "error" }, + { + "inputs": [], + "name": "OnlyCiphernodeRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCiphernodeRegistryOrSlashingManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySlashingManager", + "type": "error" + }, { "inputs": [ { @@ -362,6 +457,22 @@ "name": "ThresholdTooSmall", "type": "error" }, + { + "inputs": [], + "name": "TreasuryRequired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "UtilizationBpsExceedsMax", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -2448,11 +2559,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615ca0806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461492c565b61095a565b005b6102f06103003660046149dc565b610ba1565b61032d6103133660046149f7565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614a1b565b60405180910390f35b61032d6103513660046149f7565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614a3d565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046149dc565b610c89565b6102f06103b4366004614a65565b610d2e565b6103db6103c73660046149f7565b5f908152600f602052604090205460ff1690565b60405161033a9190614aa7565b6103fb6103f63660046149f7565b610d42565b60405161033a9e9d9c9b9a99989796959493929190614af3565b6104286104233660046149f7565b610f6c565b60405161033a9190614ce3565b6104546104433660046149f7565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614cf5565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046149f7565b611269565b6102f06104c13660046149dc565b6112f8565b6104d96104d4366004614d2e565b61138b565b60405161033a929190614d65565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614d7d565b611be6565b6102f061052c366004614dae565b611c7e565b6102f061053f3660046149f7565b611d07565b6102f0610552366004614ddc565b611e05565b60015461032d906001600160a01b031681565b61032d611ef8565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f26565b60405161033a9190614dfc565b6102f06105ba3660046149f7565b611f6c565b61059f6105cd3660046149f7565b612114565b6105e56105e03660046149f7565b61216d565b60405161033a929190614e1d565b61032d6106013660046149f7565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614e70565b612194565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ee7565b61032d61078e3660046149f7565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614ff4565b61242c565b6102f06107c9366004614d7d565b61265c565b6102f06107dc366004615099565b6126f3565b6102f06107ef3660046149dc565b6127de565b6102f0610802366004614ddc565b612885565b6104906108153660046149dc565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614dae565b612968565b6102f06108533660046149f7565b612a1b565b61087a6108663660046149f7565b5f908152600d602052604090205460ff1690565b60405161033a91906150d1565b6102f06108953660046150df565b612a58565b6104546108a8366004614d2e565b612dae565b6102f06108bb3660046149dc565b613332565b6102f06108ce3660046150f9565b6133cc565b60025461032d906001600160a01b031681565b6102f06108f43660046149dc565b613698565b6103db6109073660046149f7565b6136d2565b6102f061091a3660046149dc565b61386c565b61032d61092d3660046149f7565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046149dc565b613904565b5f610963613993565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a03336139bd565b610a0c88612a1b565b610a158c61386c565b610a1e8b613332565b610a278a610ba1565b610a3089610c89565b610a39876139ce565b610a428661265c565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611ef8565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613698565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613b02565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613b02565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb9190614a1b565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d23908390614a1b565b60405180910390a150565b610d36613b02565b610d3f816139ce565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990615130565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590615130565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90615130565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614611565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614a7f565b6003811115610fc257610fc2614a7f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490615130565b80601f016020809104026020016040519081016040528092919081815260200182805461106090615130565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490615130565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090615130565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90615130565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890615130565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613b02565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613b02565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d23908390614a1b565b5f611394614611565b5f6012816113a56020870187615162565b60038111156113b6576113b6614a7f565b60038111156113c7576113c7614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f816001600281106114455761144561517b565b602002015163ffffffff1611845f0160208101906114639190615162565b906114825760405163286c068d60e11b8152600401610bfb919061518f565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f24260408901356151b1565b6114fc91906151c4565b61150691906151c4565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016149dc565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016149dc565b9061158e5760405163295a6a6f60e11b8152600401610bfb9190614a1b565b505f61159986612dae565b60068054965090915085905f6115ae836151d7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff19166001179055601090945282902080543394169390931790925560165491925061168991908901356151c4565b5f878152600e60209081526040909120600101919091558186526116af90880188615162565b856020019060038111156116c5576116c5614a7f565b908160038111156116d8576116d8614a7f565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016149dc565b6001600160a01b031660a086015261173b60808801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c080870191909152611783908801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d090610100890190890161523e565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613b34565b5f6118316080890160608a016149dc565b6001600160a01b031663fefd9a8b888461184e60808d018d6151ef565b61185b60a08f018f6151ef565b8f8060c0019061186b91906151ef565b6040518963ffffffff1660e01b815260040161188e989796959493929190615281565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906152d7565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614a7f565b0217905550604082015181600201556060820151816003019060026119c892919061468e565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d908261534d565b5060e08201516008820190611a22908261534d565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a908261534d565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615402565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b309190615447565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016149dc565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614d65565b60405180910390a2885f516020615c745f395f51905f525f6001604051611bbf929190615462565b60405180910390a250505050505050915091565b611bdb613b02565b611be45f613ba1565b565b611bee613b02565b80515f5b81811015611c4257600b838281518110611c0e57611c0e61517b565b6020026020010151604051611c23919061547d565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615493565b60405180910390a15050565b611c86613b02565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d305760405162461bcd60e51b8152600401610bfb906154f6565b5f818152600d602052604090205460ff166001816006811115611d5557611d55614a7f565b14611d7a57816001826040516337e1404160e01b8152600401610bfb93929190615527565b5f828152600d60205260409020805460ff19166002179055601554611d9f90426151c4565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615c745f395f51905f5260016002604051611df9929190615462565b60405180910390a25050565b5f546001600160a01b03163314611e2e5760405162461bcd60e51b8152600401610bfb906154f6565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e5e57611e5e614a7f565b14611e8357836002826040516337e1404160e01b8152600401610bfb93929190615527565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615c745f395f51905f5260026003604051611eea929190615462565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9157611f91614a7f565b14611fce5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610bfb565b5f828152600c6020526040902054806120205760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610bfb565b5f838152600c6020526040812081905561203984613c11565b5f858152601160205260409020546002549192506001600160a01b03908116916120669183911685613d05565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061209c90889087908790879060040161558b565b5f604051808303815f87803b1580156120b3575f5ffd5b505af11580156120c5573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612105929190918252602082015260400190565b60405180910390a25050505050565b61213560405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661218a8482613d30565b9250925050915091565b5f5f61219f87610f6c565b5f888152600d602052604090205490915060ff1660038160068111156121c7576121c7614a7f565b14886003839091926121ef576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015612253576040516308f3034360e31b815260048101929092526024820152604401610bfb565b505060608301516020015189904281111561228a5760405163017e35e560e71b815260048101929092526024820152604401610bfb565b50506101608301518990156122b557604051637eb9cea960e11b8152600401610bfb91815260200190565b505f88886040516122c79291906155c2565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560175490915061230990426151c4565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90612356908d9085908c908c906004016155d1565b6020604051808303815f875af1158015612372573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123969190615447565b94508888866123ba57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123ee9291906155f0565b60405180910390a2895f516020615c745f395f51905f5260036004604051612417929190615462565b60405180910390a25050505095945050505050565b5f5f61243789610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561245f5761245f614a7f565b148a600483909192612487576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124ea576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016125078a8c83615603565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161254b9291906155c2565b6040519081900381206001600160e01b031960e084901b168252612579918c908c908c908c906004016156b7565b602060405180830381865afa158015612594573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125b89190615447565b93508989856125dc57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b50506125e78b613eb8565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161261d94939291906156ef565b60405180910390a28a5f516020615c745f395f51905f5260046005604051612646929190615462565b60405180910390a2505050979650505050505050565b612664613b02565b80515f5b818110156126c3576001600b8483815181106126865761268661517b565b602002602001015160405161269b919061547d565b908152604051908190036020019020805491151560ff19909216919091179055600101612668565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615493565b5f546001600160a01b031633148061271557506003546001600160a01b031633145b6127615760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610bfb565b5f8160ff161180156127775750600d60ff821611155b6127bc5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b6127da828260ff16600d8111156127d5576127d5614a7f565b614334565b5050565b6127e6613b02565b6001600160a01b03811661283c5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610bfb565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612920575f5ffd5b505af1158015612932573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611df991815260200190565b612970613b02565b6001600160a01b038116158015906129a157505f828152600960205260409020546001600160a01b03828116911614155b82906129c3576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612a23613b02565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b612a60613b02565b612710612a756101208301610100840161573a565b61ffff161115612abd5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610bfb565b612710612ad26101408301610120840161573a565b61ffff161115612b195760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610bfb565b612710612b2e6101608301610140840161573a565b61ffff161115612b805760405162461bcd60e51b815260206004820152601c60248201527f444b47207574696c697a6174696f6e20657863656564732031303025000000006044820152606401610bfb565b612710612b956101808301610160840161573a565b61ffff161115612be75760405162461bcd60e51b815260206004820181905260248201527f436f6d70757465207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612710612bfc6101a08301610180840161573a565b61ffff161115612c4e5760405162461bcd60e51b815260206004820181905260248201527f44656372797074207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612c606101408201610120830161573a565b61ffff161580612c8957505f612c7d610100830160e084016149dc565b6001600160a01b031614155b612ce75760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610bfb565b612cf96101e082016101c08301615771565b63ffffffff16612d116101c083016101a08401615771565b63ffffffff161015612d6f5760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610bfb565b806018612d7c82826157b0565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d23919061596e565b5f80601281612dc06020860186615162565b6003811115612dd157612dd1614a7f565b6003811115612de257612de2614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612e09579050505050505090505f81600160028110612e6057612e6061517b565b602002015163ffffffff1611835f016020810190612e7e9190615162565b90612e9d5760405163286c068d60e11b8152600401610bfb919061518f565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612fc8576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612fa79190615162565b90612fc65760405163010b971d60e31b8152600401610bfb919061518f565b505b6101c081015163ffffffff1615613017576101c081015184519063ffffffff908116908216101561301557604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b604086013560208701358110156130445760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f91612710916130629161ffff1690615a78565b61306c9190615a8f565b61271061ffff1683610160015161ffff1660156001015461308d9190615a78565b6130979190615a8f565b61271061ffff1684610140015161ffff1660155f01546130b79190615a78565b6130c19190615a8f565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa15801561310d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313191906152d7565b61313b91906151c4565b61314591906151b1565b61314f91906151c4565b61315991906151c4565b61316391906151c4565b90505f6131716001866151b1565b61317c906002615a78565b613187906002615a78565b6131929060066151c4565b90505f85845f01516131a49190615a78565b9050818685602001516131b79190615a78565b6131c19190615a78565b6131cb90826151c4565b905060018611156132135760026131e36001886151b1565b6131ed9088615a78565b85604001516131fc9190615a78565b6132069190615a8f565b61321090826151c4565b90505b81868560c001516132249190615a78565b61322e9190615a78565b61323890826151c4565b90508286856060015161324b9190615a78565b6132559190615a78565b61325f90826151c4565b90508484608001516132719190615a78565b61327b90826151c4565b905060018511156132c35760026132936001876151b1565b61329d9087615a78565b85604001516132ac9190615a78565b6132b69190615a8f565b6132c090826151c4565b90505b60a08401516132d290826151c4565b610100850151909150612710906132ed9061ffff16826151c4565b6132f79083615a78565b6133019190615a8f565b9750878061332557604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b61333a613b02565b6001600160a01b0381161580159061336057506001546001600160a01b03828116911614155b8190613380576040516320252f0b60e01b8152600401610bfb9190614a1b565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d23908390614a1b565b6133d4613b02565b6133e16020820182615771565b63ffffffff166133f76040830160208401615771565b63ffffffff161015801561341c57505f6134146020830183615771565b63ffffffff16115b61345c5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610bfb565b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215613594576101a081015163ffffffff166135456040840160208501615771565b63ffffffff1610156135945760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610bfb565b6101c081015163ffffffff1615613608576101c081015163ffffffff166135be6020840184615771565b63ffffffff1610156136085760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610bfb565b8160125f85600381111561361e5761361e614a7f565b600381111561362f5761362f614a7f565b815260208101919091526040015f206136499160026146cc565b5082600381111561365c5761365c614a7f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161368b9190615aae565b60405180910390a2505050565b6136a0613b02565b6001600160a01b0381166136c9575f604051631e4fbdf760e01b8152600401610bfb9190614a1b565b610d3f81613ba1565b5f818152600d602052604081205460ff16818160068111156136f6576136f6614a7f565b0361371b57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561372f5761372f614a7f565b036137505760405163462c7bed60e01b815260048101849052602401610bfb565b600681600681111561376457613764614a7f565b0361378557604051633de16e3560e11b815260048101849052602401610bfb565b5f6137908483613d30565b93509050806137b557604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156137fe576137fe614a7f565b0217905550835f516020615c745f395f51905f52836006604051613823929190615462565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161385d929190615aee565b60405180910390a25050919050565b613874613b02565b6001600160a01b0381161580159061389957505f546001600160a01b03828116911614155b81906138b9576040516375ac4eb760e11b8152600401610bfb9190614a1b565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d23908390614a1b565b6001600160a01b0381165f90815260076020526040902054819060ff16156139405760405163b29d459560e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d23908390614a1b565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6139c561448f565b610d3f816144b4565b8035613a115760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610bfb565b5f816020013511613a5d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610bfb565b5f816040013511613aac5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610bfb565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b33613b0b611ef8565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb9190614a1b565b6040516001600160a01b038481166024830152838116604483015260648201839052613b9b9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506144bc565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613c3957613c39614a7f565b1480613c565750600281600d811115613c5457613c54614a7f565b145b15613c8e575f5b604051908082528060200260200182016040528015613c86578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613cf457506040513d5f823e601f3d908101601f19168201604052613cf19190810190615b09565b60015b613cfe575f613c5d565b9392505050565b613d2b83846001600160a01b031663a9059cbb8585604051602401613b69929190615b98565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613daa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dce91906152d7565b90506001856006811115613de457613de4614a7f565b148015613df057508042115b15613e0357600180935093505050613eb1565b6002856006811115613e1757613e17614a7f565b148015613e245750815142115b15613e385760016003935093505050613eb1565b6003856006811115613e4c57613e4c614a7f565b148015613e5c5750816020015142115b15613e705760016006935093505050613eb1565b6004856006811115613e8457613e84614a7f565b148015613e945750816040015142115b15613ea8576001600a935093505050613eb1565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613efd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613f249190810190615b09565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613fc2576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613f8e90889088908690600401615bb1565b5f604051808303815f87803b158015613fa5575f5ffd5b505af1158015613fb7573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b0316811580159061400257506001600160a01b03811615155b1561403e5761271061401861ffff841687615a78565b6140229190615a8f565b9250821561403e5761403e6001600160a01b0385168285613d05565b5f61404984876151b1565b9050865f036140fd575f898152601060205260409020546001600160a01b0316801580159061407757505f82115b15614090576140906001600160a01b0387168284613d05565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906140c4908d908d908b90600401615bb1565b5f604051808303815f87803b1580156140db575f5ffd5b505af11580156140ed573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115614116576141166147ce565b60405190808252806020026020018201604052801561413f578160200160208202803683370190505b5090505f61414d8984615a8f565b90505f805b8a81101561418c578284828151811061416d5761416d61517b565b602090810291909101015261418283836151c4565b9150600101614152565b505f61419882866151b1565b905080156141d55780846141ad60018e6151b1565b815181106141bd576141bd61517b565b602002602001018181516141d191906151c4565b9052505b6001546141ef906001600160a01b038b811691168761451f565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161423393929190615c11565b5f604051808303815f87803b15801561424a575f5ffd5b505af115801561425c573d5f5f3e3d5ffd5b505060015461427a92506001600160a01b038c81169250165f61451f565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516142ac929190615c46565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016142f893929190615bb1565b5f604051808303815f87803b15801561430f575f5ffd5b505af1158015614321573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561435857614358614a7f565b0361437d57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561439157614391614a7f565b036143b25760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156143c6576143c6614a7f565b036143e757604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561443057614430614a7f565b0217905550825f516020615c745f395f51905f52826006604051614455929190615462565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161368b929190615aee565b6144976145af565b611be457604051631afcd79f60e31b815260040160405180910390fd5b6136a061448f565b5f5f60205f8451602086015f885af1806144db576040513d5f823e3d81fd5b50505f513d915081156144f25780600114156144ff565b6001600160a01b0384163b155b15613b9b5783604051635274afe760e01b8152600401610bfb9190614a1b565b5f836001600160a01b031663095ea7b38484604051602401614542929190615b98565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061457b84826145c8565b613b9b576145a584856001600160a01b031663095ea7b3865f604051602401613b69929190615b98565b613b9b84826144bc565b5f6145b8613993565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614607575081156145f95780600114614607565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614639614768565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156146bc579160200282015b828111156146bc5782518255916020019190600101906146a1565b506146c8929150614786565b5090565b6001830191839082156146bc579160200282015f5b8382111561472b57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146e1565b801561475b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261472b565b50506146c8929150614786565b60405180604001604052806002906020820280368337509192915050565b5b808211156146c8575f8155600101614787565b6001600160a01b0381168114610d3f575f5ffd5b80356147b98161479a565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561480a5761480a6147ce565b604052919050565b5f6001600160401b0382111561482a5761482a6147ce565b5060051b60200190565b5f82601f830112614843575f5ffd5b81356001600160401b0381111561485c5761485c6147ce565b61486f601f8201601f19166020016147e2565b818152846020838601011115614883575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126148ae575f5ffd5b81356148c16148bc82614812565b6147e2565b8082825260208201915060208360051b8601019250858311156148e2575f5ffd5b602085015b838110156149225780356001600160401b03811115614904575f5ffd5b614913886020838a0101614834565b845250602092830192016148e7565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614944575f5ffd5b883561494f8161479a565b9750602089013561495f8161479a565b9650604089013561496f8161479a565b9550606089013561497f8161479a565b9450608089013561498f8161479a565b935060a089013592506149a58a60c08b016147be565b91506101208901356001600160401b038111156149c0575f5ffd5b6149cc8b828c0161489f565b9150509295985092959890939650565b5f602082840312156149ec575f5ffd5b8135613cfe8161479a565b5f60208284031215614a07575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147b9575f5ffd5b5f5f60408385031215614a4e575f5ffd5b614a5783614a2f565b946020939093013593505050565b5f60608284031215614a75575f5ffd5b613cfe83836147be565b634e487b7160e01b5f52602160045260245ffd5b600e8110614aa357614aa3614a7f565b9052565b602081016139b78284614a93565b60048110614aa357614aa3614a7f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614b03602082018f614ab5565b8c60408201528b6060820152614b1c608082018c614a0e565b6101c060a08201525f614b336101c083018c614ac5565b82810360c0840152614b45818c614ac5565b9050614b5460e084018b614a0e565b614b6261010084018a614a0e565b8761012084015286610140840152828103610160840152614b838187614ac5565b915050614b94610180830185614a0e565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015613b9b578151845260209384019390910190600101614bb3565b805182525f6020820151614be96020850182614ab5565b50604082015160408401526060820151614c066060850182614bb0565b50608082015160a084015260a0820151614c2360c0850182614a0e565b5060c082015161020060e0850152614c3f610200850182614ac5565b905060e0830151848203610100860152614c598282614ac5565b915050610100830151614c70610120860182614a0e565b50610120830151614c85610140860182614a0e565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614cb78282614ac5565b9150506101a0830151614cce6101c0860182614a0e565b506101c08301518015156101e0860152613c86565b602081525f613cfe6020830184614bd2565b5f60208284031215614d05575f5ffd5b81356001600160401b03811115614d1a575f5ffd5b614d2684828501614834565b949350505050565b5f60208284031215614d3e575f5ffd5b81356001600160401b03811115614d53575f5ffd5b82016101008185031215613cfe575f5ffd5b828152604060208201525f614d266040830184614bd2565b5f60208284031215614d8d575f5ffd5b81356001600160401b03811115614da2575f5ffd5b614d268482850161489f565b5f5f60408385031215614dbf575f5ffd5b823591506020830135614dd18161479a565b809150509250929050565b5f5f60408385031215614ded575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016139b7565b821515815260408101613cfe6020830184614a93565b5f5f83601f840112614e43575f5ffd5b5081356001600160401b03811115614e59575f5ffd5b602083019150836020828501011115613eb1575f5ffd5b5f5f5f5f5f60608688031215614e84575f5ffd5b8535945060208601356001600160401b03811115614ea0575f5ffd5b614eac88828901614e33565b90955093505060408601356001600160401b03811115614eca575f5ffd5b614ed688828901614e33565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614f4160e0840182614a0e565b50610100830151614f5961010084018261ffff169052565b50610120830151614f7161012084018261ffff169052565b50610140830151614f8961014084018261ffff169052565b50610160830151614fa161016084018261ffff169052565b50610180830151614fb961018084018261ffff169052565b506101a0830151614fd36101a084018263ffffffff169052565b506101c0830151614fed6101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a03121561500a575f5ffd5b8735965060208801356001600160401b03811115615026575f5ffd5b6150328a828b01614e33565b90975095505060408801356001600160401b03811115615050575f5ffd5b61505c8a828b01614e33565b90955093505060608801356001600160401b0381111561507a575f5ffd5b6150868a828b01614e33565b989b979a50959850939692959293505050565b5f5f604083850312156150aa575f5ffd5b82359150602083013560ff81168114614dd1575f5ffd5b60078110614aa357614aa3614a7f565b602081016139b782846150c1565b5f6101e08284031280156150f1575f5ffd5b509092915050565b5f5f6060838503121561510a575f5ffd5b61511383614a2f565b915083606084011115615124575f5ffd5b50926020919091019150565b600181811c9082168061514457607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215615172575f5ffd5b613cfe82614a2f565b634e487b7160e01b5f52603260045260245ffd5b602081016139b78284614ab5565b634e487b7160e01b5f52601160045260245ffd5b818103818111156139b7576139b761519d565b808201808211156139b7576139b761519d565b5f600182016151e8576151e861519d565b5060010190565b5f5f8335601e19843603018112615204575f5ffd5b8301803591506001600160401b0382111561521d575f5ffd5b602001915036819003821315613eb1575f5ffd5b8015158114610d3f575f5ffd5b5f6020828403121561524e575f5ffd5b8135613cfe81615231565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6152a060a08301888a615259565b82810360608401526152b3818789615259565b905082810360808401526152c8818587615259565b9b9a5050505050505050505050565b5f602082840312156152e7575f5ffd5b5051919050565b601f821115613d2b57805f5260205f20601f840160051c810160208510156153135750805b601f840160051c820191505b81811015615332575f815560010161531f565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615366576153666147ce565b61537a816153748454615130565b846152ee565b6020601f8211600181146153a7575f83156153955750848201515b61539f8482615339565b855550615332565b5f84815260208120601f198516915b828110156153d657878501518255602094850194600190920191016153b6565b50848210156153f357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561543c57815163ffffffff16835260209283019290910190600101615417565b505050949350505050565b5f60208284031215615457575f5ffd5b8151613cfe81615231565b6040810161547082856150c1565b613cfe60208301846150c1565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156154ea57603f198786030184526154d5858351614ac5565b945060209384019391909101906001016154b9565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161553b60208301856150c1565b614d2660408301846150c1565b5f8151808452602084019350602083015f5b828110156155815781516001600160a01b031686526020958601959091019060010161555a565b5093949350505050565b848152836020820152608060408201525f6155a96080830185615548565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f614607606083018486615259565b602081525f614d26602083018486615259565b6001600160401b0383111561561a5761561a6147ce565b61562e836156288354615130565b836152ee565b5f601f84116001811461565a575f85156156485750838201355b6156528682615339565b845550615332565b5f83815260208120601f198716915b828110156156895786850135825560209485019460019092019101615669565b50868210156156a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6156d0606083018688615259565b82810360408401526156e3818587615259565b98975050505050505050565b604081525f615702604083018688615259565b8281036020840152615715818587615259565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356147b981615720565b5f6020828403121561574a575f5ffd5b8135613cfe81615720565b63ffffffff81168114610d3f575f5ffd5b80356147b981615755565b5f60208284031215615781575f5ffd5b8135613cfe81615755565b5f81356139b78161479a565b5f81356139b781615720565b5f81356139b781615755565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161582061580360e0850161578c565b82546001600160a01b0319166001600160a01b0391909116178255565b6158506158306101008501615798565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6158806158606101208501615798565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6158b06158906101408501615798565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6158e06158c06101608501615798565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6159106158f06101808501615798565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161593c6159256101a085016157a4565b825463ffffffff191663ffffffff91909116178255565b613d2b61594c6101c085016157a4565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016159bf60e084016147ae565b6159cc60e0840182614a0e565b506159da610100840161572f565b61ffff166101008301526159f1610120840161572f565b61ffff16610120830152615a08610140840161572f565b61ffff16610140830152615a1f610160840161572f565b61ffff16610160830152615a36610180840161572f565b61ffff16610180830152615a4d6101a08401615766565b63ffffffff166101a0830152615a666101c08401615766565b63ffffffff81166101c0840152614fed565b80820281158282048414176139b7576139b761519d565b5f82615aa957634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b6002811015615ae5578135615aca81615755565b63ffffffff1683526020928301929190910190600101615ab6565b50505092915050565b60408101615afc82856150c1565b613cfe6020830184614a93565b5f60208284031215615b19575f5ffd5b81516001600160401b03811115615b2e575f5ffd5b8201601f81018413615b3e575f5ffd5b8051615b4c6148bc82614812565b8082825260208201915060208360051b850101925086831115615b6d575f5ffd5b6020840193505b82841015614607578351615b878161479a565b825260209384019390910190615b74565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615bc96060830185615548565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615581578151865260209586019590910190600101615bf3565b6001600160a01b03841681526060602082018190525f90615c3490830185615548565b82810360408401526146078185615be1565b604081525f615c586040830185615548565b8281036020840152615c6a8185615be1565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461492c565b61095a565b005b6102f06103003660046149dc565b610ba1565b61032d6103133660046149f7565b5f908152600960205260409020546001600160a01b031690565b60405161033a9190614a1b565b60405180910390f35b61032d6103513660046149f7565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614a3d565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046149dc565b610c89565b6102f06103b4366004614a65565b610d2e565b6103db6103c73660046149f7565b5f908152600f602052604090205460ff1690565b60405161033a9190614aa7565b6103fb6103f63660046149f7565b610d42565b60405161033a9e9d9c9b9a99989796959493929190614af3565b6104286104233660046149f7565b610f6c565b60405161033a9190614ce3565b6104546104433660046149f7565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614cf5565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046149f7565b611269565b6102f06104c13660046149dc565b6112f8565b6104d96104d4366004614d2e565b61138b565b60405161033a929190614d65565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614d7d565b611be6565b6102f061052c366004614dae565b611c7e565b6102f061053f3660046149f7565b611d07565b6102f0610552366004614ddc565b611e05565b60015461032d906001600160a01b031681565b61032d611ef8565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f26565b60405161033a9190614dfc565b6102f06105ba3660046149f7565b611f6c565b61059f6105cd3660046149f7565b612114565b6105e56105e03660046149f7565b61216d565b60405161033a929190614e1d565b61032d6106013660046149f7565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614e70565b612194565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ee7565b61032d61078e3660046149f7565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614ff4565b61242c565b6102f06107c9366004614d7d565b61265c565b6102f06107dc366004615099565b6126f3565b6102f06107ef3660046149dc565b6127de565b6102f0610802366004614ddc565b612885565b6104906108153660046149dc565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614dae565b612968565b6102f06108533660046149f7565b612a1b565b61087a6108663660046149f7565b5f908152600d602052604090205460ff1690565b60405161033a91906150d1565b6102f06108953660046150df565b612a58565b6104546108a8366004614d2e565b612dae565b6102f06108bb3660046149dc565b613332565b6102f06108ce3660046150f9565b6133cc565b60025461032d906001600160a01b031681565b6102f06108f43660046149dc565b613698565b6103db6109073660046149f7565b6136d2565b6102f061091a3660046149dc565b61386c565b61032d61092d3660046149f7565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046149dc565b613904565b5f610963613993565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a03336139bd565b610a0c88612a1b565b610a158c61386c565b610a1e8b613332565b610a278a610ba1565b610a3089610c89565b610a39876139ce565b610a428661265c565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611ef8565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613698565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613b02565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613b02565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb9190614a1b565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d23908390614a1b565b60405180910390a150565b610d36613b02565b610d3f816139ce565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990615130565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590615130565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90615130565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90615130565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614611565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614a7f565b6003811115610fc257610fc2614a7f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490615130565b80601f016020809104026020016040519081016040528092919081815260200182805461106090615130565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490615130565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090615130565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90615130565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890615130565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613b02565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613b02565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d23908390614a1b565b5f611394614611565b5f6012816113a56020870187615162565b60038111156113b6576113b6614a7f565b60038111156113c7576113c7614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f816001600281106114455761144561517b565b602002015163ffffffff1611845f0160208101906114639190615162565b906114825760405163286c068d60e11b8152600401610bfb919061518f565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f24260408901356151b1565b6114fc91906151c4565b61150691906151c4565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016149dc565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016149dc565b9061158e5760405163295a6a6f60e11b8152600401610bfb9190614a1b565b505f61159986612dae565b60068054965090915085905f6115ae836151d7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff19166001179055601090945282902080543394169390931790925560165491925061168991908901356151c4565b5f878152600e60209081526040909120600101919091558186526116af90880188615162565b856020019060038111156116c5576116c5614a7f565b908160038111156116d8576116d8614a7f565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016149dc565b6001600160a01b031660a086015261173b60808801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c080870191909152611783908801886151ef565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d090610100890190890161523e565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613b34565b5f6118316080890160608a016149dc565b6001600160a01b031663fefd9a8b888461184e60808d018d6151ef565b61185b60a08f018f6151ef565b8f8060c0019061186b91906151ef565b6040518963ffffffff1660e01b815260040161188e989796959493929190615281565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906152d7565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614a7f565b0217905550604082015181600201556060820151816003019060026119c892919061468e565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d908261534d565b5060e08201516008820190611a22908261534d565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a908261534d565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615402565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b309190615447565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016149dc565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614d65565b60405180910390a2885f516020615c745f395f51905f525f6001604051611bbf929190615462565b60405180910390a250505050505050915091565b611bdb613b02565b611be45f613ba1565b565b611bee613b02565b80515f5b81811015611c4257600b838281518110611c0e57611c0e61517b565b6020026020010151604051611c23919061547d565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615493565b60405180910390a15050565b611c86613b02565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d305760405162461bcd60e51b8152600401610bfb906154f6565b5f818152600d602052604090205460ff166001816006811115611d5557611d55614a7f565b14611d7a57816001826040516337e1404160e01b8152600401610bfb93929190615527565b5f828152600d60205260409020805460ff19166002179055601554611d9f90426151c4565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615c745f395f51905f5260016002604051611df9929190615462565b60405180910390a25050565b5f546001600160a01b03163314611e2e5760405162461bcd60e51b8152600401610bfb906154f6565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e5e57611e5e614a7f565b14611e8357836002826040516337e1404160e01b8152600401610bfb93929190615527565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615c745f395f51905f5260026003604051611eea929190615462565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9157611f91614a7f565b14611fce5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b6044820152606401610bfb565b5f828152600c6020526040902054806120205760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b6044820152606401610bfb565b5f838152600c6020526040812081905561203984613c11565b5f858152601160205260409020546002549192506001600160a01b03908116916120669183911685613d05565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061209c90889087908790879060040161558b565b5f604051808303815f87803b1580156120b3575f5ffd5b505af11580156120c5573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612105929190918252602082015260400190565b60405180910390a25050505050565b61213560405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661218a8482613d30565b9250925050915091565b5f5f61219f87610f6c565b5f888152600d602052604090205490915060ff1660038160068111156121c7576121c7614a7f565b14886003839091926121ef576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015612253576040516308f3034360e31b815260048101929092526024820152604401610bfb565b505060608301516020015189904281111561228a5760405163017e35e560e71b815260048101929092526024820152604401610bfb565b50506101608301518990156122b557604051637eb9cea960e11b8152600401610bfb91815260200190565b505f88886040516122c79291906155c2565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560175490915061230990426151c4565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90612356908d9085908c908c906004016155d1565b6020604051808303815f875af1158015612372573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123969190615447565b94508888866123ba57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123ee9291906155f0565b60405180910390a2895f516020615c745f395f51905f5260036004604051612417929190615462565b60405180910390a25050505095945050505050565b5f5f61243789610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561245f5761245f614a7f565b148a600483909192612487576040516337e1404160e01b8152600401610bfb93929190615527565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124ea576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016125078a8c83615603565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161254b9291906155c2565b6040519081900381206001600160e01b031960e084901b168252612579918c908c908c908c906004016156b7565b602060405180830381865afa158015612594573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125b89190615447565b93508989856125dc57604051632f9f8ab960e01b8152600401610bfb9291906155f0565b50506125e78b613eb8565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161261d94939291906156ef565b60405180910390a28a5f516020615c745f395f51905f5260046005604051612646929190615462565b60405180910390a2505050979650505050505050565b612664613b02565b80515f5b818110156126c3576001600b8483815181106126865761268661517b565b602002602001015160405161269b919061547d565b908152604051908190036020019020805491151560ff19909216919091179055600101612668565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615493565b5f546001600160a01b031633148061271557506003546001600160a01b031633145b6127615760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d6772000000006044820152606401610bfb565b5f8160ff161180156127775750600d60ff821611155b6127bc5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b6127da828260ff16600d8111156127d5576127d5614a7f565b614334565b5050565b6127e6613b02565b6001600160a01b03811661283c5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b6044820152606401610bfb565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612920575f5ffd5b505af1158015612932573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611df991815260200190565b612970613b02565b6001600160a01b038116158015906129a157505f828152600960205260409020546001600160a01b03828116911614155b82906129c3576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612a23613b02565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b612a60613b02565b612710612a756101208301610100840161573a565b61ffff161115612abd5760405162461bcd60e51b81526020600482015260136024820152724d617267696e2065786365656473203130302560681b6044820152606401610bfb565b612710612ad26101408301610120840161573a565b61ffff161115612b195760405162461bcd60e51b815260206004820152601260248201527153686172652065786365656473203130302560701b6044820152606401610bfb565b612710612b2e6101608301610140840161573a565b61ffff161115612b805760405162461bcd60e51b815260206004820152601c60248201527f444b47207574696c697a6174696f6e20657863656564732031303025000000006044820152606401610bfb565b612710612b956101808301610160840161573a565b61ffff161115612be75760405162461bcd60e51b815260206004820181905260248201527f436f6d70757465207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612710612bfc6101a08301610180840161573a565b61ffff161115612c4e5760405162461bcd60e51b815260206004820181905260248201527f44656372797074207574696c697a6174696f6e206578636565647320313030256044820152606401610bfb565b612c606101408201610120830161573a565b61ffff161580612c8957505f612c7d610100830160e084016149dc565b6001600160a01b031614155b612ce75760405162461bcd60e51b815260206004820152602960248201527f5472656173757279207265717569726564207768656e2070726f746f636f6c2060448201526807368617265203e20360bc1b6064820152608401610bfb565b612cf96101e082016101c08301615771565b63ffffffff16612d116101c083016101a08401615771565b63ffffffff161015612d6f5760405162461bcd60e51b815260206004820152602160248201527f4d696e2073697a65206d757374206265203e3d206d696e207468726573686f6c6044820152601960fa1b6064820152608401610bfb565b806018612d7c82826157b0565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d23919061596e565b5f80601281612dc06020860186615162565b6003811115612dd157612dd1614a7f565b6003811115612de257612de2614a7f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612e09579050505050505090505f81600160028110612e6057612e6061517b565b602002015163ffffffff1611835f016020810190612e7e9190615162565b90612e9d5760405163286c068d60e11b8152600401610bfb919061518f565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612fc8576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612fa79190615162565b90612fc65760405163010b971d60e31b8152600401610bfb919061518f565b505b6101c081015163ffffffff1615613017576101c081015184519063ffffffff908116908216101561301557604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b604086013560208701358110156130445760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f91612710916130629161ffff1690615a78565b61306c9190615a8f565b61271061ffff1683610160015161ffff1660156001015461308d9190615a78565b6130979190615a8f565b61271061ffff1684610140015161ffff1660155f01546130b79190615a78565b6130c19190615a8f565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa15801561310d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313191906152d7565b61313b91906151c4565b61314591906151b1565b61314f91906151c4565b61315991906151c4565b61316391906151c4565b90505f6131716001866151b1565b61317c906002615a78565b613187906002615a78565b6131929060066151c4565b90505f85845f01516131a49190615a78565b9050818685602001516131b79190615a78565b6131c19190615a78565b6131cb90826151c4565b905060018611156132135760026131e36001886151b1565b6131ed9088615a78565b85604001516131fc9190615a78565b6132069190615a8f565b61321090826151c4565b90505b81868560c001516132249190615a78565b61322e9190615a78565b61323890826151c4565b90508286856060015161324b9190615a78565b6132559190615a78565b61325f90826151c4565b90508484608001516132719190615a78565b61327b90826151c4565b905060018511156132c35760026132936001876151b1565b61329d9087615a78565b85604001516132ac9190615a78565b6132b69190615a8f565b6132c090826151c4565b90505b60a08401516132d290826151c4565b610100850151909150612710906132ed9061ffff16826151c4565b6132f79083615a78565b6133019190615a8f565b9750878061332557604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b61333a613b02565b6001600160a01b0381161580159061336057506001546001600160a01b03828116911614155b8190613380576040516320252f0b60e01b8152600401610bfb9190614a1b565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d23908390614a1b565b6133d4613b02565b6133e16020820182615771565b63ffffffff166133f76040830160208401615771565b63ffffffff161015801561341c57505f6134146020830183615771565b63ffffffff16115b61345c5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b6044820152606401610bfb565b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215613594576101a081015163ffffffff166135456040840160208501615771565b63ffffffff1610156135945760405162461bcd60e51b815260206004820152601860248201527742656c6f77206d696e20636f6d6d69747465652073697a6560401b6044820152606401610bfb565b6101c081015163ffffffff1615613608576101c081015163ffffffff166135be6020840184615771565b63ffffffff1610156136085760405162461bcd60e51b815260206004820152601360248201527210995b1bddc81b5a5b881d1a1c995cda1bdb19606a1b6044820152606401610bfb565b8160125f85600381111561361e5761361e614a7f565b600381111561362f5761362f614a7f565b815260208101919091526040015f206136499160026146cc565b5082600381111561365c5761365c614a7f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa8360405161368b9190615aae565b60405180910390a2505050565b6136a0613b02565b6001600160a01b0381166136c9575f604051631e4fbdf760e01b8152600401610bfb9190614a1b565b610d3f81613ba1565b5f818152600d602052604081205460ff16818160068111156136f6576136f6614a7f565b0361371b57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561372f5761372f614a7f565b036137505760405163462c7bed60e01b815260048101849052602401610bfb565b600681600681111561376457613764614a7f565b0361378557604051633de16e3560e11b815260048101849052602401610bfb565b5f6137908483613d30565b93509050806137b557604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156137fe576137fe614a7f565b0217905550835f516020615c745f395f51905f52836006604051613823929190615462565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161385d929190615aee565b60405180910390a25050919050565b613874613b02565b6001600160a01b0381161580159061389957505f546001600160a01b03828116911614155b81906138b9576040516375ac4eb760e11b8152600401610bfb9190614a1b565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d23908390614a1b565b6001600160a01b0381165f90815260076020526040902054819060ff16156139405760405163b29d459560e01b8152600401610bfb9190614a1b565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d23908390614a1b565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b6139c561448f565b610d3f816144b4565b8035613a115760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b6044820152606401610bfb565b5f816020013511613a5d5760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b6044820152606401610bfb565b5f816040013511613aac5760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b6044820152606401610bfb565b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b33613b0b611ef8565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb9190614a1b565b6040516001600160a01b038481166024830152838116604483015260648201839052613b9b9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506144bc565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613c3957613c39614a7f565b1480613c565750600281600d811115613c5457613c54614a7f565b145b15613c8e575f5b604051908082528060200260200182016040528015613c86578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613cf457506040513d5f823e601f3d908101601f19168201604052613cf19190810190615b09565b60015b613cfe575f613c5d565b9392505050565b613d2b83846001600160a01b031663a9059cbb8585604051602401613b69929190615b98565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613daa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dce91906152d7565b90506001856006811115613de457613de4614a7f565b148015613df057508042115b15613e0357600180935093505050613eb1565b6002856006811115613e1757613e17614a7f565b148015613e245750815142115b15613e385760016003935093505050613eb1565b6003856006811115613e4c57613e4c614a7f565b148015613e5c5750816020015142115b15613e705760016006935093505050613eb1565b6004856006811115613e8457613e84614a7f565b148015613e945750816040015142115b15613ea8576001600a935093505050613eb1565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613efd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613f249190810190615b09565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613fc2576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613f8e90889088908690600401615bb1565b5f604051808303815f87803b158015613fa5575f5ffd5b505af1158015613fb7573d5f5f3e3d5ffd5b505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b0316811580159061400257506001600160a01b03811615155b1561403e5761271061401861ffff841687615a78565b6140229190615a8f565b9250821561403e5761403e6001600160a01b0385168285613d05565b5f61404984876151b1565b9050865f036140fd575f898152601060205260409020546001600160a01b0316801580159061407757505f82115b15614090576140906001600160a01b0387168284613d05565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f15906140c4908d908d908b90600401615bb1565b5f604051808303815f87803b1580156140db575f5ffd5b505af11580156140ed573d5f5f3e3d5ffd5b5050505050505050505050505050565b5f876001600160401b03811115614116576141166147ce565b60405190808252806020026020018201604052801561413f578160200160208202803683370190505b5090505f61414d8984615a8f565b90505f805b8a81101561418c578284828151811061416d5761416d61517b565b602090810291909101015261418283836151c4565b9150600101614152565b505f61419882866151b1565b905080156141d55780846141ad60018e6151b1565b815181106141bd576141bd61517b565b602002602001018181516141d191906151c4565b9052505b6001546141ef906001600160a01b038b811691168761451f565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161423393929190615c11565b5f604051808303815f87803b15801561424a575f5ffd5b505af115801561425c573d5f5f3e3d5ffd5b505060015461427a92506001600160a01b038c81169250165f61451f565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516142ac929190615c46565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016142f893929190615bb1565b5f604051808303815f87803b15801561430f575f5ffd5b505af1158015614321573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561435857614358614a7f565b0361437d57826001826040516337e1404160e01b8152600401610bfb93929190615527565b600581600681111561439157614391614a7f565b036143b25760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156143c6576143c6614a7f565b036143e757604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561443057614430614a7f565b0217905550825f516020615c745f395f51905f52826006604051614455929190615462565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161368b929190615aee565b6144976145af565b611be457604051631afcd79f60e31b815260040160405180910390fd5b6136a061448f565b5f5f60205f8451602086015f885af1806144db576040513d5f823e3d81fd5b50505f513d915081156144f25780600114156144ff565b6001600160a01b0384163b155b15613b9b5783604051635274afe760e01b8152600401610bfb9190614a1b565b5f836001600160a01b031663095ea7b38484604051602401614542929190615b98565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061457b84826145c8565b613b9b576145a584856001600160a01b031663095ea7b3865f604051602401613b69929190615b98565b613b9b84826144bc565b5f6145b8613993565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614607575081156145f95780600114614607565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614639614768565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156146bc579160200282015b828111156146bc5782518255916020019190600101906146a1565b506146c8929150614786565b5090565b6001830191839082156146bc579160200282015f5b8382111561472b57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146e1565b801561475b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261472b565b50506146c8929150614786565b60405180604001604052806002906020820280368337509192915050565b5b808211156146c8575f8155600101614787565b6001600160a01b0381168114610d3f575f5ffd5b80356147b98161479a565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561480a5761480a6147ce565b604052919050565b5f6001600160401b0382111561482a5761482a6147ce565b5060051b60200190565b5f82601f830112614843575f5ffd5b81356001600160401b0381111561485c5761485c6147ce565b61486f601f8201601f19166020016147e2565b818152846020838601011115614883575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126148ae575f5ffd5b81356148c16148bc82614812565b6147e2565b8082825260208201915060208360051b8601019250858311156148e2575f5ffd5b602085015b838110156149225780356001600160401b03811115614904575f5ffd5b614913886020838a0101614834565b845250602092830192016148e7565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614944575f5ffd5b883561494f8161479a565b9750602089013561495f8161479a565b9650604089013561496f8161479a565b9550606089013561497f8161479a565b9450608089013561498f8161479a565b935060a089013592506149a58a60c08b016147be565b91506101208901356001600160401b038111156149c0575f5ffd5b6149cc8b828c0161489f565b9150509295985092959890939650565b5f602082840312156149ec575f5ffd5b8135613cfe8161479a565b5f60208284031215614a07575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147b9575f5ffd5b5f5f60408385031215614a4e575f5ffd5b614a5783614a2f565b946020939093013593505050565b5f60608284031215614a75575f5ffd5b613cfe83836147be565b634e487b7160e01b5f52602160045260245ffd5b600e8110614aa357614aa3614a7f565b9052565b602081016139b78284614a93565b60048110614aa357614aa3614a7f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614b03602082018f614ab5565b8c60408201528b6060820152614b1c608082018c614a0e565b6101c060a08201525f614b336101c083018c614ac5565b82810360c0840152614b45818c614ac5565b9050614b5460e084018b614a0e565b614b6261010084018a614a0e565b8761012084015286610140840152828103610160840152614b838187614ac5565b915050614b94610180830185614a0e565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015613b9b578151845260209384019390910190600101614bb3565b805182525f6020820151614be96020850182614ab5565b50604082015160408401526060820151614c066060850182614bb0565b50608082015160a084015260a0820151614c2360c0850182614a0e565b5060c082015161020060e0850152614c3f610200850182614ac5565b905060e0830151848203610100860152614c598282614ac5565b915050610100830151614c70610120860182614a0e565b50610120830151614c85610140860182614a0e565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614cb78282614ac5565b9150506101a0830151614cce6101c0860182614a0e565b506101c08301518015156101e0860152613c86565b602081525f613cfe6020830184614bd2565b5f60208284031215614d05575f5ffd5b81356001600160401b03811115614d1a575f5ffd5b614d2684828501614834565b949350505050565b5f60208284031215614d3e575f5ffd5b81356001600160401b03811115614d53575f5ffd5b82016101008185031215613cfe575f5ffd5b828152604060208201525f614d266040830184614bd2565b5f60208284031215614d8d575f5ffd5b81356001600160401b03811115614da2575f5ffd5b614d268482850161489f565b5f5f60408385031215614dbf575f5ffd5b823591506020830135614dd18161479a565b809150509250929050565b5f5f60408385031215614ded575f5ffd5b50508035926020909101359150565b815181526020808301519082015260408083015190820152606081016139b7565b821515815260408101613cfe6020830184614a93565b5f5f83601f840112614e43575f5ffd5b5081356001600160401b03811115614e59575f5ffd5b602083019150836020828501011115613eb1575f5ffd5b5f5f5f5f5f60608688031215614e84575f5ffd5b8535945060208601356001600160401b03811115614ea0575f5ffd5b614eac88828901614e33565b90955093505060408601356001600160401b03811115614eca575f5ffd5b614ed688828901614e33565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614f4160e0840182614a0e565b50610100830151614f5961010084018261ffff169052565b50610120830151614f7161012084018261ffff169052565b50610140830151614f8961014084018261ffff169052565b50610160830151614fa161016084018261ffff169052565b50610180830151614fb961018084018261ffff169052565b506101a0830151614fd36101a084018263ffffffff169052565b506101c0830151614fed6101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a03121561500a575f5ffd5b8735965060208801356001600160401b03811115615026575f5ffd5b6150328a828b01614e33565b90975095505060408801356001600160401b03811115615050575f5ffd5b61505c8a828b01614e33565b90955093505060608801356001600160401b0381111561507a575f5ffd5b6150868a828b01614e33565b989b979a50959850939692959293505050565b5f5f604083850312156150aa575f5ffd5b82359150602083013560ff81168114614dd1575f5ffd5b60078110614aa357614aa3614a7f565b602081016139b782846150c1565b5f6101e08284031280156150f1575f5ffd5b509092915050565b5f5f6060838503121561510a575f5ffd5b61511383614a2f565b915083606084011115615124575f5ffd5b50926020919091019150565b600181811c9082168061514457607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215615172575f5ffd5b613cfe82614a2f565b634e487b7160e01b5f52603260045260245ffd5b602081016139b78284614ab5565b634e487b7160e01b5f52601160045260245ffd5b818103818111156139b7576139b761519d565b808201808211156139b7576139b761519d565b5f600182016151e8576151e861519d565b5060010190565b5f5f8335601e19843603018112615204575f5ffd5b8301803591506001600160401b0382111561521d575f5ffd5b602001915036819003821315613eb1575f5ffd5b8015158114610d3f575f5ffd5b5f6020828403121561524e575f5ffd5b8135613cfe81615231565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6152a060a08301888a615259565b82810360608401526152b3818789615259565b905082810360808401526152c8818587615259565b9b9a5050505050505050505050565b5f602082840312156152e7575f5ffd5b5051919050565b601f821115613d2b57805f5260205f20601f840160051c810160208510156153135750805b601f840160051c820191505b81811015615332575f815560010161531f565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615366576153666147ce565b61537a816153748454615130565b846152ee565b6020601f8211600181146153a7575f83156153955750848201515b61539f8482615339565b855550615332565b5f84815260208120601f198516915b828110156153d657878501518255602094850194600190920191016153b6565b50848210156153f357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561543c57815163ffffffff16835260209283019290910190600101615417565b505050949350505050565b5f60208284031215615457575f5ffd5b8151613cfe81615231565b6040810161547082856150c1565b613cfe60208301846150c1565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156154ea57603f198786030184526154d5858351614ac5565b945060209384019391909101906001016154b9565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161553b60208301856150c1565b614d2660408301846150c1565b5f8151808452602084019350602083015f5b828110156155815781516001600160a01b031686526020958601959091019060010161555a565b5093949350505050565b848152836020820152608060408201525f6155a96080830185615548565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f614607606083018486615259565b602081525f614d26602083018486615259565b6001600160401b0383111561561a5761561a6147ce565b61562e836156288354615130565b836152ee565b5f601f84116001811461565a575f85156156485750838201355b6156528682615339565b845550615332565b5f83815260208120601f198716915b828110156156895786850135825560209485019460019092019101615669565b50868210156156a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6156d0606083018688615259565b82810360408401526156e3818587615259565b98975050505050505050565b604081525f615702604083018688615259565b8281036020840152615715818587615259565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356147b981615720565b5f6020828403121561574a575f5ffd5b8135613cfe81615720565b63ffffffff81168114610d3f575f5ffd5b80356147b981615755565b5f60208284031215615781575f5ffd5b8135613cfe81615755565b5f81356139b78161479a565b5f81356139b781615720565b5f81356139b781615755565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161582061580360e0850161578c565b82546001600160a01b0319166001600160a01b0391909116178255565b6158506158306101008501615798565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6158806158606101208501615798565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6158b06158906101408501615798565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6158e06158c06101608501615798565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6159106158f06101808501615798565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161593c6159256101a085016157a4565b825463ffffffff191663ffffffff91909116178255565b613d2b61594c6101c085016157a4565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016159bf60e084016147ae565b6159cc60e0840182614a0e565b506159da610100840161572f565b61ffff166101008301526159f1610120840161572f565b61ffff16610120830152615a08610140840161572f565b61ffff16610140830152615a1f610160840161572f565b61ffff16610160830152615a36610180840161572f565b61ffff16610180830152615a4d6101a08401615766565b63ffffffff166101a0830152615a666101c08401615766565b63ffffffff81166101c0840152614fed565b80820281158282048414176139b7576139b761519d565b5f82615aa957634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b6002811015615ae5578135615aca81615755565b63ffffffff1683526020928301929190910190600101615ab6565b50505092915050565b60408101615afc82856150c1565b613cfe6020830184614a93565b5f60208284031215615b19575f5ffd5b81516001600160401b03811115615b2e575f5ffd5b8201601f81018413615b3e575f5ffd5b8051615b4c6148bc82614812565b8082825260208201915060208360051b850101925086831115615b6d575f5ffd5b6020840193505b82841015614607578351615b878161479a565b825260209384019390910190615b74565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615bc96060830185615548565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615581578151865260209586019590910190600101615bf3565b6001600160a01b03841681526060602082018190525f90615c3490830185615548565b82810360408401526146078185615be1565b604081525f615c586040830185615548565b8281036020840152615c6a8185615be1565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615a72806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461472f565b61095a565b005b6102f06103003660046147df565b610ba1565b61032d6103133660046147fa565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061481e565b60405180910390f35b61032d6103513660046147fa565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614840565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046147df565b610c89565b6102f06103b4366004614868565b610d2e565b6103db6103c73660046147fa565b5f908152600f602052604090205460ff1690565b60405161033a91906148aa565b6103fb6103f63660046147fa565b610d42565b60405161033a9e9d9c9b9a999897969594939291906148f6565b6104286104233660046147fa565b610f6c565b60405161033a9190614ae6565b6104546104433660046147fa565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614af8565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046147fa565b611269565b6102f06104c13660046147df565b6112f8565b6104d96104d4366004614b31565b61138b565b60405161033a929190614b68565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614b80565b611be6565b6102f061052c366004614bb1565b611c7e565b6102f061053f3660046147fa565b611d07565b6102f0610552366004614bdf565b611e06565b60015461032d906001600160a01b031681565b61032d611efa565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f28565b60405161033a9190614bff565b6102f06105ba3660046147fa565b611f6e565b61059f6105cd3660046147fa565b6120dc565b6105e56105e03660046147fa565b612135565b60405161033a929190614c20565b61032d6106013660046147fa565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614c73565b61215c565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614cea565b61032d61078e3660046147fa565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614df7565b6123f4565b6102f06107c9366004614b80565b612624565b6102f06107dc366004614e9c565b6126bb565b6102f06107ef3660046147df565b612777565b6102f0610802366004614bdf565b61281e565b6104906108153660046147df565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614bb1565b6128db565b6102f06108533660046147fa565b61298e565b61087a6108663660046147fa565b5f908152600d602052604090205460ff1690565b60405161033a9190614ed4565b6102f0610895366004614ee2565b6129cb565b6104546108a8366004614b31565b612c58565b6102f06108bb3660046147df565b6131dc565b6102f06108ce366004614efc565b613276565b60025461032d906001600160a01b031681565b6102f06108f43660046147df565b613523565b6103db6109073660046147fa565b61355d565b6102f061091a3660046147df565b6136f7565b61032d61092d3660046147fa565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046147df565b61378f565b5f61096361381e565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a0333613848565b610a0c8861298e565b610a158c6136f7565b610a1e8b6131dc565b610a278a610ba1565b610a3089610c89565b610a3987613859565b610a4286612624565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611efa565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613523565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613916565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613916565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb919061481e565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d2390839061481e565b60405180910390a150565b610d36613916565b610d3f81613859565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990614f33565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590614f33565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90614f33565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614414565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614882565b6003811115610fc257610fc2614882565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490614f33565b80601f016020809104026020016040519081016040528092919081815260200182805461106090614f33565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490614f33565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090614f33565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90614f33565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890614f33565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613916565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613916565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb919061481e565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d2390839061481e565b5f611394614414565b5f6012816113a56020870187614f65565b60038111156113b6576113b6614882565b60038111156113c7576113c7614882565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f8160016002811061144557611445614f7e565b602002015163ffffffff1611845f0160208101906114639190614f65565b906114825760405163286c068d60e11b8152600401610bfb9190614f92565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f2426040890135614fb4565b6114fc9190614fc7565b6115069190614fc7565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016147df565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016147df565b9061158e5760405163295a6a6f60e11b8152600401610bfb919061481e565b505f61159986612c58565b60068054965090915085905f6115ae83614fda565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506116899190890135614fc7565b5f878152600e60209081526040909120600101919091558186526116af90880188614f65565b856020019060038111156116c5576116c5614882565b908160038111156116d8576116d8614882565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016147df565b6001600160a01b031660a086015261173b6080880188614ff2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261178390880188614ff2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d0906101008901908901615041565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613948565b5f6118316080890160608a016147df565b6001600160a01b031663fefd9a8b888461184e60808d018d614ff2565b61185b60a08f018f614ff2565b8f8060c0019061186b9190614ff2565b6040518963ffffffff1660e01b815260040161188e989796959493929190615084565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906150da565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614882565b0217905550604082015181600201556060820151816003019060026119c8929190614491565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d9082615150565b5060e08201516008820190611a229082615150565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a9082615150565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615205565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b30919061524a565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016147df565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614b68565b60405180910390a2885f516020615a465f395f51905f525f6001604051611bbf929190615265565b60405180910390a250505050505050915091565b611bdb613916565b611be45f6139b5565b565b611bee613916565b80515f5b81811015611c4257600b838281518110611c0e57611c0e614f7e565b6020026020010151604051611c239190615280565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615296565b60405180910390a15050565b611c86613916565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d315760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff166001816006811115611d5657611d56614882565b14611d7b57816001826040516337e1404160e01b8152600401610bfb939291906152f9565b5f828152600d60205260409020805460ff19166002179055601554611da09042614fc7565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615a465f395f51905f5260016002604051611dfa929190615265565b60405180910390a25050565b5f546001600160a01b03163314611e305760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e6057611e60614882565b14611e8557836002826040516337e1404160e01b8152600401610bfb939291906152f9565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615a465f395f51905f5260026003604051611eec929190615265565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9357611f93614882565b148290611fb657604051637cb2d48360e11b8152600401610bfb91815260200190565b505f828152600c60205260409020548281611fe7576040516345ba89d560e11b8152600401610bfb91815260200190565b505f838152600c6020526040812081905561200184613a25565b5f858152601160205260409020546002549192506001600160a01b039081169161202e9183911685613b19565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061206490889087908790879060040161535d565b5f604051808303815f87803b15801561207b575f5ffd5b505af115801561208d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a073178484516040516120cd929190918252602082015260400190565b60405180910390a25050505050565b6120fd60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121528482613b44565b9250925050915091565b5f5f61216787610f6c565b5f888152600d602052604090205490915060ff16600381600681111561218f5761218f614882565b14886003839091926121b7576040516337e1404160e01b8152600401610bfb939291906152f9565b5050505f888152600e602090815260409182902082516060810184528154815260018201549281018390526002909101549281019290925289904281101561221b576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50506060830151602001518990428111156122525760405163017e35e560e71b815260048101929092526024820152604401610bfb565b505061016083015189901561227d57604051637eb9cea960e11b8152600401610bfb91815260200190565b505f888860405161228f929190615394565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506122d19042614fc7565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf9061231e908d9085908c908c906004016153a3565b6020604051808303815f875af115801561233a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061235e919061524a565b945088888661238257604051632f9f8ab960e01b8152600401610bfb9291906153c2565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123b69291906153c2565b60405180910390a2895f516020615a465f395f51905f52600360046040516123df929190615265565b60405180910390a25050505095945050505050565b5f5f6123ff89610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561242757612427614882565b148a60048390919261244f576040516337e1404160e01b8152600401610bfb939291906152f9565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124b2576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016124cf8a8c836153d5565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b604051612513929190615394565b6040519081900381206001600160e01b031960e084901b168252612541918c908c908c908c90600401615489565b602060405180830381865afa15801561255c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612580919061524a565b93508989856125a457604051632f9f8ab960e01b8152600401610bfb9291906153c2565b50506125af8b613ccc565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b6040516125e594939291906154c1565b60405180910390a28a5f516020615a465f395f51905f526004600560405161260e929190615265565b60405180910390a2505050979650505050505050565b61262c613916565b80515f5b8181101561268b576001600b84838151811061264e5761264e614f7e565b60200260200101516040516126639190615280565b908152604051908190036020019020805491151560ff19909216919091179055600101612630565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615296565b5f546001600160a01b03163314806126dd57506003546001600160a01b031633145b6126fa57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156127105750600d60ff821611155b6127555760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b612773828260ff16600d81111561276e5761276e614882565b614137565b5050565b61277f613916565b6001600160a01b0381166127d55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612849576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612893575f5ffd5b505af11580156128a5573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611dfa91815260200190565b6128e3613916565b6001600160a01b0381161580159061291457505f828152600960205260409020546001600160a01b03828116911614155b8290612936576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612996613916565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b6129d3613916565b6127106129e86101208301610100840161550c565b61ffff161115612a006101208301610100840161550c565b90612a25576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a3b6101408301610120840161550c565b61ffff161115612a536101408301610120840161550c565b90612a78576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a8e6101608301610140840161550c565b61ffff161115612aa66101608301610140840161550c565b90612acb57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612ae16101808301610160840161550c565b61ffff161115612af96101808301610160840161550c565b90612b1e57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612b346101a08301610180840161550c565b61ffff161115612b4c6101a08301610180840161550c565b90612b7157604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612b846101408201610120830161550c565b61ffff161580612bad57505f612ba1610100830160e084016147df565b6001600160a01b031614155b612bca5760405163015f92ff60e51b815260040160405180910390fd5b612bdc6101e082016101c08301615543565b63ffffffff16612bf46101c083016101a08401615543565b63ffffffff161015612c19576040516392f55c6560e01b815260040160405180910390fd5b806018612c268282615582565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d239190615740565b5f80601281612c6a6020860186614f65565b6003811115612c7b57612c7b614882565b6003811115612c8c57612c8c614882565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612cb3579050505050505090505f81600160028110612d0a57612d0a614f7e565b602002015163ffffffff1611835f016020810190612d289190614f65565b90612d475760405163286c068d60e11b8152600401610bfb9190614f92565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612e72576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612e519190614f65565b90612e705760405163010b971d60e31b8152600401610bfb9190614f92565b505b6101c081015163ffffffff1615612ec1576101c081015184519063ffffffff9081169082161015612ebf57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b60408601356020870135811015612eee5760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f9161271091612f0c9161ffff169061584a565b612f169190615861565b61271061ffff1683610160015161ffff16601560010154612f37919061584a565b612f419190615861565b61271061ffff1684610140015161ffff1660155f0154612f61919061584a565b612f6b9190615861565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612fb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fdb91906150da565b612fe59190614fc7565b612fef9190614fb4565b612ff99190614fc7565b6130039190614fc7565b61300d9190614fc7565b90505f61301b600186614fb4565b61302690600261584a565b61303190600261584a565b61303c906006614fc7565b90505f85845f015161304e919061584a565b905081868560200151613061919061584a565b61306b919061584a565b6130759082614fc7565b905060018611156130bd57600261308d600188614fb4565b613097908861584a565b85604001516130a6919061584a565b6130b09190615861565b6130ba9082614fc7565b90505b81868560c001516130ce919061584a565b6130d8919061584a565b6130e29082614fc7565b9050828685606001516130f5919061584a565b6130ff919061584a565b6131099082614fc7565b905084846080015161311b919061584a565b6131259082614fc7565b9050600185111561316d57600261313d600187614fb4565b613147908761584a565b8560400151613156919061584a565b6131609190615861565b61316a9082614fc7565b90505b60a084015161317c9082614fc7565b610100850151909150612710906131979061ffff1682614fc7565b6131a1908361584a565b6131ab9190615861565b975087806131cf57604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b6131e4613916565b6001600160a01b0381161580159061320a57506001546001600160a01b03828116911614155b819061322a576040516320252f0b60e01b8152600401610bfb919061481e565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d2390839061481e565b61327e613916565b61328b6020820182615543565b63ffffffff166132a16040830160208401615543565b63ffffffff16101580156132c657505f6132be6020830183615543565b63ffffffff16115b6132e357604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c08301521561341c576101a081015163ffffffff166133cc6040840160208501615543565b63ffffffff1610156133e46040840160208501615543565b826101a00151909161341957604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610bfb565b50505b6101c081015163ffffffff1615613493576101c081015163ffffffff166134466020840184615543565b63ffffffff16101561345b6020840184615543565b826101c0015190916134905760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610bfb565b50505b8160125f8560038111156134a9576134a9614882565b60038111156134ba576134ba614882565b815260208101919091526040015f206134d49160026144cf565b508260038111156134e7576134e7614882565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516135169190615880565b60405180910390a2505050565b61352b613916565b6001600160a01b038116613554575f604051631e4fbdf760e01b8152600401610bfb919061481e565b610d3f816139b5565b5f818152600d602052604081205460ff168181600681111561358157613581614882565b036135a657826001826040516337e1404160e01b8152600401610bfb939291906152f9565b60058160068111156135ba576135ba614882565b036135db5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156135ef576135ef614882565b0361361057604051633de16e3560e11b815260048101849052602401610bfb565b5f61361b8483613b44565b935090508061364057604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561368957613689614882565b0217905550835f516020615a465f395f51905f528360066040516136ae929190615265565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516136e89291906158c0565b60405180910390a25050919050565b6136ff613916565b6001600160a01b0381161580159061372457505f546001600160a01b03828116911614155b8190613744576040516375ac4eb760e11b8152600401610bfb919061481e565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d2390839061481e565b6001600160a01b0381165f90815260076020526040902054819060ff16156137cb5760405163b29d459560e01b8152600401610bfb919061481e565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d2390839061481e565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613850614292565b610d3f816142b7565b80356138785760405163055f269d60e01b815260040160405180910390fd5b5f81602001351161389c5760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138c05760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b3361391f611efa565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb919061481e565b6040516001600160a01b0384811660248301528381166044830152606482018390526139af9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142bf565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a4d57613a4d614882565b1480613a6a5750600281600d811115613a6857613a68614882565b145b15613aa2575f5b604051908082528060200260200182016040528015613a9a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613b0857506040513d5f823e601f3d908101601f19168201604052613b0591908101906158db565b60015b613b12575f613a71565b9392505050565b613b3f83846001600160a01b031663a9059cbb858560405160240161397d92919061596a565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bbe573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613be291906150da565b90506001856006811115613bf857613bf8614882565b148015613c0457508042115b15613c1757600180935093505050613cc5565b6002856006811115613c2b57613c2b614882565b148015613c385750815142115b15613c4c5760016003935093505050613cc5565b6003856006811115613c6057613c60614882565b148015613c705750816020015142115b15613c845760016006935093505050613cc5565b6004856006811115613c9857613c98614882565b148015613ca85750816040015142115b15613cbc576001600a935093505050613cc5565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613d11573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d3891908101906158db565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dd6576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613da290889088908690600401615983565b5f604051808303815f87803b158015613db9575f5ffd5b505af1158015613dcb573d5f5f3e3d5ffd5b505050505050505050565b825f03613e77575f858152601060205260409020546001600160a01b03168015613e0e57613e0e6001600160a01b0383168285613b19565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e4290899089908790600401615983565b5f604051808303815f87803b158015613e59575f5ffd5b505af1158015613e6b573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613eb757506001600160a01b03811615155b15613ef357612710613ecd61ffff84168761584a565b613ed79190615861565b92508215613ef357613ef36001600160a01b0385168285613b19565b5f613efe8487614fb4565b90505f876001600160401b03811115613f1957613f196145d1565b604051908082528060200260200182016040528015613f42578160200160208202803683370190505b5090505f613f508984615861565b90505f805b8a811015613f8f5782848281518110613f7057613f70614f7e565b6020908102919091010152613f858383614fc7565b9150600101613f55565b505f613f9b8286614fb4565b90508015613fd8578084613fb060018e614fb4565b81518110613fc057613fc0614f7e565b60200260200101818151613fd49190614fc7565b9052505b600154613ff2906001600160a01b038b8116911687614322565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401614036939291906159e3565b5f604051808303815f87803b15801561404d575f5ffd5b505af115801561405f573d5f5f3e3d5ffd5b505060015461407d92506001600160a01b038c81169250165f614322565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516140af929190615a18565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140fb93929190615983565b5f604051808303815f87803b158015614112575f5ffd5b505af1158015614124573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561415b5761415b614882565b0361418057826001826040516337e1404160e01b8152600401610bfb939291906152f9565b600581600681111561419457614194614882565b036141b55760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156141c9576141c9614882565b036141ea57604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561423357614233614882565b0217905550825f516020615a465f395f51905f52826006604051614258929190615265565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516135169291906158c0565b61429a6143b2565b611be457604051631afcd79f60e31b815260040160405180910390fd5b61352b614292565b5f5f60205f8451602086015f885af1806142de576040513d5f823e3d81fd5b50505f513d915081156142f5578060011415614302565b6001600160a01b0384163b155b156139af5783604051635274afe760e01b8152600401610bfb919061481e565b5f836001600160a01b031663095ea7b3848460405160240161434592919061596a565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061437e84826143cb565b6139af576143a884856001600160a01b031663095ea7b3865f60405160240161397d92919061596a565b6139af84826142bf565b5f6143bb61381e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561440a575081156143fc578060011461440a565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161443c61456b565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156144bf579160200282015b828111156144bf5782518255916020019190600101906144a4565b506144cb929150614589565b5090565b6001830191839082156144bf579160200282015f5b8382111561452e57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144e4565b801561455e5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261452e565b50506144cb929150614589565b60405180604001604052806002906020820280368337509192915050565b5b808211156144cb575f815560010161458a565b6001600160a01b0381168114610d3f575f5ffd5b80356145bc8161459d565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561460d5761460d6145d1565b604052919050565b5f6001600160401b0382111561462d5761462d6145d1565b5060051b60200190565b5f82601f830112614646575f5ffd5b81356001600160401b0381111561465f5761465f6145d1565b614672601f8201601f19166020016145e5565b818152846020838601011115614686575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126146b1575f5ffd5b81356146c46146bf82614615565b6145e5565b8082825260208201915060208360051b8601019250858311156146e5575f5ffd5b602085015b838110156147255780356001600160401b03811115614707575f5ffd5b614716886020838a0101614637565b845250602092830192016146ea565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614747575f5ffd5b88356147528161459d565b975060208901356147628161459d565b965060408901356147728161459d565b955060608901356147828161459d565b945060808901356147928161459d565b935060a089013592506147a88a60c08b016145c1565b91506101208901356001600160401b038111156147c3575f5ffd5b6147cf8b828c016146a2565b9150509295985092959890939650565b5f602082840312156147ef575f5ffd5b8135613b128161459d565b5f6020828403121561480a575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106145bc575f5ffd5b5f5f60408385031215614851575f5ffd5b61485a83614832565b946020939093013593505050565b5f60608284031215614878575f5ffd5b613b1283836145c1565b634e487b7160e01b5f52602160045260245ffd5b600e81106148a6576148a6614882565b9052565b602081016138428284614896565b600481106148a6576148a6614882565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614906602082018f6148b8565b8c60408201528b606082015261491f608082018c614811565b6101c060a08201525f6149366101c083018c6148c8565b82810360c0840152614948818c6148c8565b905061495760e084018b614811565b61496561010084018a614811565b876101208401528661014084015282810361016084015261498681876148c8565b915050614997610180830185614811565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156139af5781518452602093840193909101906001016149b6565b805182525f60208201516149ec60208501826148b8565b50604082015160408401526060820151614a0960608501826149b3565b50608082015160a084015260a0820151614a2660c0850182614811565b5060c082015161020060e0850152614a426102008501826148c8565b905060e0830151848203610100860152614a5c82826148c8565b915050610100830151614a73610120860182614811565b50610120830151614a88610140860182614811565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614aba82826148c8565b9150506101a0830151614ad16101c0860182614811565b506101c08301518015156101e0860152613a9a565b602081525f613b1260208301846149d5565b5f60208284031215614b08575f5ffd5b81356001600160401b03811115614b1d575f5ffd5b614b2984828501614637565b949350505050565b5f60208284031215614b41575f5ffd5b81356001600160401b03811115614b56575f5ffd5b82016101008185031215613b12575f5ffd5b828152604060208201525f614b2960408301846149d5565b5f60208284031215614b90575f5ffd5b81356001600160401b03811115614ba5575f5ffd5b614b29848285016146a2565b5f5f60408385031215614bc2575f5ffd5b823591506020830135614bd48161459d565b809150509250929050565b5f5f60408385031215614bf0575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101613842565b821515815260408101613b126020830184614896565b5f5f83601f840112614c46575f5ffd5b5081356001600160401b03811115614c5c575f5ffd5b602083019150836020828501011115613cc5575f5ffd5b5f5f5f5f5f60608688031215614c87575f5ffd5b8535945060208601356001600160401b03811115614ca3575f5ffd5b614caf88828901614c36565b90955093505060408601356001600160401b03811115614ccd575f5ffd5b614cd988828901614c36565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d4460e0840182614811565b50610100830151614d5c61010084018261ffff169052565b50610120830151614d7461012084018261ffff169052565b50610140830151614d8c61014084018261ffff169052565b50610160830151614da461016084018261ffff169052565b50610180830151614dbc61018084018261ffff169052565b506101a0830151614dd66101a084018263ffffffff169052565b506101c0830151614df06101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614e0d575f5ffd5b8735965060208801356001600160401b03811115614e29575f5ffd5b614e358a828b01614c36565b90975095505060408801356001600160401b03811115614e53575f5ffd5b614e5f8a828b01614c36565b90955093505060608801356001600160401b03811115614e7d575f5ffd5b614e898a828b01614c36565b989b979a50959850939692959293505050565b5f5f60408385031215614ead575f5ffd5b82359150602083013560ff81168114614bd4575f5ffd5b600781106148a6576148a6614882565b602081016138428284614ec4565b5f6101e0828403128015614ef4575f5ffd5b509092915050565b5f5f60608385031215614f0d575f5ffd5b614f1683614832565b915083606084011115614f27575f5ffd5b50926020919091019150565b600181811c90821680614f4757607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614f75575f5ffd5b613b1282614832565b634e487b7160e01b5f52603260045260245ffd5b6020810161384282846148b8565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561384257613842614fa0565b8082018082111561384257613842614fa0565b5f60018201614feb57614feb614fa0565b5060010190565b5f5f8335601e19843603018112615007575f5ffd5b8301803591506001600160401b03821115615020575f5ffd5b602001915036819003821315613cc5575f5ffd5b8015158114610d3f575f5ffd5b5f60208284031215615051575f5ffd5b8135613b1281615034565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6150a360a08301888a61505c565b82810360608401526150b681878961505c565b905082810360808401526150cb81858761505c565b9b9a5050505050505050505050565b5f602082840312156150ea575f5ffd5b5051919050565b601f821115613b3f57805f5260205f20601f840160051c810160208510156151165750805b601f840160051c820191505b81811015615135575f8155600101615122565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615169576151696145d1565b61517d816151778454614f33565b846150f1565b6020601f8211600181146151aa575f83156151985750848201515b6151a2848261513c565b855550615135565b5f84815260208120601f198516915b828110156151d957878501518255602094850194600190920191016151b9565b50848210156151f657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561523f57815163ffffffff1683526020928301929091019060010161521a565b505050949350505050565b5f6020828403121561525a575f5ffd5b8151613b1281615034565b604081016152738285614ec4565b613b126020830184614ec4565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156152ed57603f198786030184526152d88583516148c8565b945060209384019391909101906001016152bc565b50929695505050505050565b8381526060810161530d6020830185614ec4565b614b296040830184614ec4565b5f8151808452602084019350602083015f5b828110156153535781516001600160a01b031686526020958601959091019060010161532c565b5093949350505050565b848152836020820152608060408201525f61537b608083018561531a565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61440a60608301848661505c565b602081525f614b2960208301848661505c565b6001600160401b038311156153ec576153ec6145d1565b615400836153fa8354614f33565b836150f1565b5f601f84116001811461542c575f851561541a5750838201355b615424868261513c565b845550615135565b5f83815260208120601f198716915b8281101561545b578685013582556020948501946001909201910161543b565b5086821015615477575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6154a260608301868861505c565b82810360408401526154b581858761505c565b98975050505050505050565b604081525f6154d460408301868861505c565b82810360208401526154e781858761505c565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356145bc816154f2565b5f6020828403121561551c575f5ffd5b8135613b12816154f2565b63ffffffff81168114610d3f575f5ffd5b80356145bc81615527565b5f60208284031215615553575f5ffd5b8135613b1281615527565b5f81356138428161459d565b5f8135613842816154f2565b5f813561384281615527565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016155f26155d560e0850161555e565b82546001600160a01b0319166001600160a01b0391909116178255565b615622615602610100850161556a565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b615652615632610120850161556a565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b615682615662610140850161556a565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6156b2615692610160850161556a565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6156e26156c2610180850161556a565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161570e6156f76101a08501615576565b825463ffffffff191663ffffffff91909116178255565b613b3f61571e6101c08501615576565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161579160e084016145b1565b61579e60e0840182614811565b506157ac6101008401615501565b61ffff166101008301526157c36101208401615501565b61ffff166101208301526157da6101408401615501565b61ffff166101408301526157f16101608401615501565b61ffff166101608301526158086101808401615501565b61ffff1661018083015261581f6101a08401615538565b63ffffffff166101a08301526158386101c08401615538565b63ffffffff81166101c0840152614df0565b808202811582820484141761384257613842614fa0565b5f8261587b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156158b757813561589c81615527565b63ffffffff1683526020928301929190910190600101615888565b50505092915050565b604081016158ce8285614ec4565b613b126020830184614896565b5f602082840312156158eb575f5ffd5b81516001600160401b03811115615900575f5ffd5b8201601f81018413615910575f5ffd5b805161591e6146bf82614615565b8082825260208201915060208360051b85010192508683111561593f575f5ffd5b6020840193505b8284101561440a5783516159598161459d565b825260209384019390910190615946565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f61599b606083018561531a565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156153535781518652602095860195909101906001016159c5565b6001600160a01b03841681526060602082018190525f90615a069083018561531a565b828103604084015261440a81856159b3565b604081525f615a2a604083018561531a565b8281036020840152615a3c81856159b3565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb36600461472f565b61095a565b005b6102f06103003660046147df565b610ba1565b61032d6103133660046147fa565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061481e565b60405180910390f35b61032d6103513660046147fa565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614840565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046147df565b610c89565b6102f06103b4366004614868565b610d2e565b6103db6103c73660046147fa565b5f908152600f602052604090205460ff1690565b60405161033a91906148aa565b6103fb6103f63660046147fa565b610d42565b60405161033a9e9d9c9b9a999897969594939291906148f6565b6104286104233660046147fa565b610f6c565b60405161033a9190614ae6565b6104546104433660046147fa565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614af8565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046147fa565b611269565b6102f06104c13660046147df565b6112f8565b6104d96104d4366004614b31565b61138b565b60405161033a929190614b68565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614b80565b611be6565b6102f061052c366004614bb1565b611c7e565b6102f061053f3660046147fa565b611d07565b6102f0610552366004614bdf565b611e06565b60015461032d906001600160a01b031681565b61032d611efa565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f28565b60405161033a9190614bff565b6102f06105ba3660046147fa565b611f6e565b61059f6105cd3660046147fa565b6120dc565b6105e56105e03660046147fa565b612135565b60405161033a929190614c20565b61032d6106013660046147fa565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614c73565b61215c565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614cea565b61032d61078e3660046147fa565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614df7565b6123f4565b6102f06107c9366004614b80565b612624565b6102f06107dc366004614e9c565b6126bb565b6102f06107ef3660046147df565b612777565b6102f0610802366004614bdf565b61281e565b6104906108153660046147df565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614bb1565b6128db565b6102f06108533660046147fa565b61298e565b61087a6108663660046147fa565b5f908152600d602052604090205460ff1690565b60405161033a9190614ed4565b6102f0610895366004614ee2565b6129cb565b6104546108a8366004614b31565b612c58565b6102f06108bb3660046147df565b6131dc565b6102f06108ce366004614efc565b613276565b60025461032d906001600160a01b031681565b6102f06108f43660046147df565b613523565b6103db6109073660046147fa565b61355d565b6102f061091a3660046147df565b6136f7565b61032d61092d3660046147fa565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046147df565b61378f565b5f61096361381e565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a0333613848565b610a0c8861298e565b610a158c6136f7565b610a1e8b6131dc565b610a278a610ba1565b610a3089610c89565b610a3987613859565b610a4286612624565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611efa565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613523565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613916565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613916565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb919061481e565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d2390839061481e565b60405180910390a150565b610d36613916565b610d3f81613859565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990614f33565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590614f33565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90614f33565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90614f33565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f74614414565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614882565b6003811115610fc257610fc2614882565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490614f33565b80601f016020809104026020016040519081016040528092919081815260200182805461106090614f33565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490614f33565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090614f33565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90614f33565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890614f33565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613916565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613916565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb919061481e565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d2390839061481e565b5f611394614414565b5f6012816113a56020870187614f65565b60038111156113b6576113b6614882565b60038111156113c7576113c7614882565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f8160016002811061144557611445614f7e565b602002015163ffffffff1611845f0160208101906114639190614f65565b906114825760405163286c068d60e11b8152600401610bfb9190614f92565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f2426040890135614fb4565b6114fc9190614fc7565b6115069190614fc7565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016147df565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016147df565b9061158e5760405163295a6a6f60e11b8152600401610bfb919061481e565b505f61159986612c58565b60068054965090915085905f6115ae83614fda565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506116899190890135614fc7565b5f878152600e60209081526040909120600101919091558186526116af90880188614f65565b856020019060038111156116c5576116c5614882565b908160038111156116d8576116d8614882565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016147df565b6001600160a01b031660a086015261173b6080880188614ff2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261178390880188614ff2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d0906101008901908901615041565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613948565b5f6118316080890160608a016147df565b6001600160a01b031663fefd9a8b888461184e60808d018d614ff2565b61185b60a08f018f614ff2565b8f8060c0019061186b9190614ff2565b6040518963ffffffff1660e01b815260040161188e989796959493929190615084565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906150da565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614882565b0217905550604082015181600201556060820151816003019060026119c8929190614491565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d9082615150565b5060e08201516008820190611a229082615150565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a9082615150565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615205565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b30919061524a565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016147df565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614b68565b60405180910390a2885f516020615a465f395f51905f525f6001604051611bbf929190615265565b60405180910390a250505050505050915091565b611bdb613916565b611be45f6139b5565b565b611bee613916565b80515f5b81811015611c4257600b838281518110611c0e57611c0e614f7e565b6020026020010151604051611c239190615280565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615296565b60405180910390a15050565b611c86613916565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d315760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff166001816006811115611d5657611d56614882565b14611d7b57816001826040516337e1404160e01b8152600401610bfb939291906152f9565b5f828152600d60205260409020805460ff19166002179055601554611da09042614fc7565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615a465f395f51905f5260016002604051611dfa929190615265565b60405180910390a25050565b5f546001600160a01b03163314611e305760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e6057611e60614882565b14611e8557836002826040516337e1404160e01b8152600401610bfb939291906152f9565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615a465f395f51905f5260026003604051611eec929190615265565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9357611f93614882565b148290611fb657604051637cb2d48360e11b8152600401610bfb91815260200190565b505f828152600c60205260409020548281611fe7576040516345ba89d560e11b8152600401610bfb91815260200190565b505f838152600c6020526040812081905561200184613a25565b5f858152601160205260409020546002549192506001600160a01b039081169161202e9183911685613b19565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061206490889087908790879060040161535d565b5f604051808303815f87803b15801561207b575f5ffd5b505af115801561208d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a073178484516040516120cd929190918252602082015260400190565b60405180910390a25050505050565b6120fd60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121528482613b44565b9250925050915091565b5f5f61216787610f6c565b5f888152600d602052604090205490915060ff16600381600681111561218f5761218f614882565b14886003839091926121b7576040516337e1404160e01b8152600401610bfb939291906152f9565b5050505f888152600e602090815260409182902082516060810184528154815260018201549281018390526002909101549281019290925289904281101561221b576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50506060830151602001518990428111156122525760405163017e35e560e71b815260048101929092526024820152604401610bfb565b505061016083015189901561227d57604051637eb9cea960e11b8152600401610bfb91815260200190565b505f888860405161228f929190615394565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506122d19042614fc7565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf9061231e908d9085908c908c906004016153a3565b6020604051808303815f875af115801561233a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061235e919061524a565b945088888661238257604051632f9f8ab960e01b8152600401610bfb9291906153c2565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123b69291906153c2565b60405180910390a2895f516020615a465f395f51905f52600360046040516123df929190615265565b60405180910390a25050505095945050505050565b5f5f6123ff89610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561242757612427614882565b148a60048390919261244f576040516337e1404160e01b8152600401610bfb939291906152f9565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124b2576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016124cf8a8c836153d5565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b604051612513929190615394565b6040519081900381206001600160e01b031960e084901b168252612541918c908c908c908c90600401615489565b602060405180830381865afa15801561255c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612580919061524a565b93508989856125a457604051632f9f8ab960e01b8152600401610bfb9291906153c2565b50506125af8b613ccc565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b6040516125e594939291906154c1565b60405180910390a28a5f516020615a465f395f51905f526004600560405161260e929190615265565b60405180910390a2505050979650505050505050565b61262c613916565b80515f5b8181101561268b576001600b84838151811061264e5761264e614f7e565b60200260200101516040516126639190615280565b908152604051908190036020019020805491151560ff19909216919091179055600101612630565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615296565b5f546001600160a01b03163314806126dd57506003546001600160a01b031633145b6126fa57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156127105750600d60ff821611155b6127555760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b612773828260ff16600d81111561276e5761276e614882565b614137565b5050565b61277f613916565b6001600160a01b0381166127d55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612849576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612893575f5ffd5b505af11580156128a5573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611dfa91815260200190565b6128e3613916565b6001600160a01b0381161580159061291457505f828152600960205260409020546001600160a01b03828116911614155b8290612936576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612996613916565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b6129d3613916565b6127106129e86101208301610100840161550c565b61ffff161115612a006101208301610100840161550c565b90612a25576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a3b6101408301610120840161550c565b61ffff161115612a536101408301610120840161550c565b90612a78576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a8e6101608301610140840161550c565b61ffff161115612aa66101608301610140840161550c565b90612acb57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612ae16101808301610160840161550c565b61ffff161115612af96101808301610160840161550c565b90612b1e57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612b346101a08301610180840161550c565b61ffff161115612b4c6101a08301610180840161550c565b90612b7157604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612b846101408201610120830161550c565b61ffff161580612bad57505f612ba1610100830160e084016147df565b6001600160a01b031614155b612bca5760405163015f92ff60e51b815260040160405180910390fd5b612bdc6101e082016101c08301615543565b63ffffffff16612bf46101c083016101a08401615543565b63ffffffff161015612c19576040516392f55c6560e01b815260040160405180910390fd5b806018612c268282615582565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d239190615740565b5f80601281612c6a6020860186614f65565b6003811115612c7b57612c7b614882565b6003811115612c8c57612c8c614882565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612cb3579050505050505090505f81600160028110612d0a57612d0a614f7e565b602002015163ffffffff1611835f016020810190612d289190614f65565b90612d475760405163286c068d60e11b8152600401610bfb9190614f92565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612e72576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612e519190614f65565b90612e705760405163010b971d60e31b8152600401610bfb9190614f92565b505b6101c081015163ffffffff1615612ec1576101c081015184519063ffffffff9081169082161015612ebf57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b60408601356020870135811015612eee5760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f9161271091612f0c9161ffff169061584a565b612f169190615861565b61271061ffff1683610160015161ffff16601560010154612f37919061584a565b612f419190615861565b61271061ffff1684610140015161ffff1660155f0154612f61919061584a565b612f6b9190615861565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612fb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fdb91906150da565b612fe59190614fc7565b612fef9190614fb4565b612ff99190614fc7565b6130039190614fc7565b61300d9190614fc7565b90505f61301b600186614fb4565b61302690600261584a565b61303190600261584a565b61303c906006614fc7565b90505f85845f015161304e919061584a565b905081868560200151613061919061584a565b61306b919061584a565b6130759082614fc7565b905060018611156130bd57600261308d600188614fb4565b613097908861584a565b85604001516130a6919061584a565b6130b09190615861565b6130ba9082614fc7565b90505b81868560c001516130ce919061584a565b6130d8919061584a565b6130e29082614fc7565b9050828685606001516130f5919061584a565b6130ff919061584a565b6131099082614fc7565b905084846080015161311b919061584a565b6131259082614fc7565b9050600185111561316d57600261313d600187614fb4565b613147908761584a565b8560400151613156919061584a565b6131609190615861565b61316a9082614fc7565b90505b60a084015161317c9082614fc7565b610100850151909150612710906131979061ffff1682614fc7565b6131a1908361584a565b6131ab9190615861565b975087806131cf57604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b6131e4613916565b6001600160a01b0381161580159061320a57506001546001600160a01b03828116911614155b819061322a576040516320252f0b60e01b8152600401610bfb919061481e565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d2390839061481e565b61327e613916565b61328b6020820182615543565b63ffffffff166132a16040830160208401615543565b63ffffffff16101580156132c657505f6132be6020830183615543565b63ffffffff16115b6132e357604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c08301521561341c576101a081015163ffffffff166133cc6040840160208501615543565b63ffffffff1610156133e46040840160208501615543565b826101a00151909161341957604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610bfb565b50505b6101c081015163ffffffff1615613493576101c081015163ffffffff166134466020840184615543565b63ffffffff16101561345b6020840184615543565b826101c0015190916134905760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610bfb565b50505b8160125f8560038111156134a9576134a9614882565b60038111156134ba576134ba614882565b815260208101919091526040015f206134d49160026144cf565b508260038111156134e7576134e7614882565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516135169190615880565b60405180910390a2505050565b61352b613916565b6001600160a01b038116613554575f604051631e4fbdf760e01b8152600401610bfb919061481e565b610d3f816139b5565b5f818152600d602052604081205460ff168181600681111561358157613581614882565b036135a657826001826040516337e1404160e01b8152600401610bfb939291906152f9565b60058160068111156135ba576135ba614882565b036135db5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156135ef576135ef614882565b0361361057604051633de16e3560e11b815260048101849052602401610bfb565b5f61361b8483613b44565b935090508061364057604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561368957613689614882565b0217905550835f516020615a465f395f51905f528360066040516136ae929190615265565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516136e89291906158c0565b60405180910390a25050919050565b6136ff613916565b6001600160a01b0381161580159061372457505f546001600160a01b03828116911614155b8190613744576040516375ac4eb760e11b8152600401610bfb919061481e565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d2390839061481e565b6001600160a01b0381165f90815260076020526040902054819060ff16156137cb5760405163b29d459560e01b8152600401610bfb919061481e565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d2390839061481e565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613850614292565b610d3f816142b7565b80356138785760405163055f269d60e01b815260040160405180910390fd5b5f81602001351161389c5760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138c05760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b3361391f611efa565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb919061481e565b6040516001600160a01b0384811660248301528381166044830152606482018390526139af9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142bf565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a4d57613a4d614882565b1480613a6a5750600281600d811115613a6857613a68614882565b145b15613aa2575f5b604051908082528060200260200182016040528015613a9a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613b0857506040513d5f823e601f3d908101601f19168201604052613b0591908101906158db565b60015b613b12575f613a71565b9392505050565b613b3f83846001600160a01b031663a9059cbb858560405160240161397d92919061596a565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bbe573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613be291906150da565b90506001856006811115613bf857613bf8614882565b148015613c0457508042115b15613c1757600180935093505050613cc5565b6002856006811115613c2b57613c2b614882565b148015613c385750815142115b15613c4c5760016003935093505050613cc5565b6003856006811115613c6057613c60614882565b148015613c705750816020015142115b15613c845760016006935093505050613cc5565b6004856006811115613c9857613c98614882565b148015613ca85750816040015142115b15613cbc576001600a935093505050613cc5565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613d11573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d3891908101906158db565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dd6576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613da290889088908690600401615983565b5f604051808303815f87803b158015613db9575f5ffd5b505af1158015613dcb573d5f5f3e3d5ffd5b505050505050505050565b825f03613e77575f858152601060205260409020546001600160a01b03168015613e0e57613e0e6001600160a01b0383168285613b19565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e4290899089908790600401615983565b5f604051808303815f87803b158015613e59575f5ffd5b505af1158015613e6b573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613eb757506001600160a01b03811615155b15613ef357612710613ecd61ffff84168761584a565b613ed79190615861565b92508215613ef357613ef36001600160a01b0385168285613b19565b5f613efe8487614fb4565b90505f876001600160401b03811115613f1957613f196145d1565b604051908082528060200260200182016040528015613f42578160200160208202803683370190505b5090505f613f508984615861565b90505f805b8a811015613f8f5782848281518110613f7057613f70614f7e565b6020908102919091010152613f858383614fc7565b9150600101613f55565b505f613f9b8286614fb4565b90508015613fd8578084613fb060018e614fb4565b81518110613fc057613fc0614f7e565b60200260200101818151613fd49190614fc7565b9052505b600154613ff2906001600160a01b038b8116911687614322565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401614036939291906159e3565b5f604051808303815f87803b15801561404d575f5ffd5b505af115801561405f573d5f5f3e3d5ffd5b505060015461407d92506001600160a01b038c81169250165f614322565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516140af929190615a18565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140fb93929190615983565b5f604051808303815f87803b158015614112575f5ffd5b505af1158015614124573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561415b5761415b614882565b0361418057826001826040516337e1404160e01b8152600401610bfb939291906152f9565b600581600681111561419457614194614882565b036141b55760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156141c9576141c9614882565b036141ea57604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561423357614233614882565b0217905550825f516020615a465f395f51905f52826006604051614258929190615265565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516135169291906158c0565b61429a6143b2565b611be457604051631afcd79f60e31b815260040160405180910390fd5b61352b614292565b5f5f60205f8451602086015f885af1806142de576040513d5f823e3d81fd5b50505f513d915081156142f5578060011415614302565b6001600160a01b0384163b155b156139af5783604051635274afe760e01b8152600401610bfb919061481e565b5f836001600160a01b031663095ea7b3848460405160240161434592919061596a565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061437e84826143cb565b6139af576143a884856001600160a01b031663095ea7b3865f60405160240161397d92919061596a565b6139af84826142bf565b5f6143bb61381e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561440a575081156143fc578060011461440a565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161443c61456b565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156144bf579160200282015b828111156144bf5782518255916020019190600101906144a4565b506144cb929150614589565b5090565b6001830191839082156144bf579160200282015f5b8382111561452e57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144e4565b801561455e5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261452e565b50506144cb929150614589565b60405180604001604052806002906020820280368337509192915050565b5b808211156144cb575f815560010161458a565b6001600160a01b0381168114610d3f575f5ffd5b80356145bc8161459d565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561460d5761460d6145d1565b604052919050565b5f6001600160401b0382111561462d5761462d6145d1565b5060051b60200190565b5f82601f830112614646575f5ffd5b81356001600160401b0381111561465f5761465f6145d1565b614672601f8201601f19166020016145e5565b818152846020838601011115614686575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126146b1575f5ffd5b81356146c46146bf82614615565b6145e5565b8082825260208201915060208360051b8601019250858311156146e5575f5ffd5b602085015b838110156147255780356001600160401b03811115614707575f5ffd5b614716886020838a0101614637565b845250602092830192016146ea565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614747575f5ffd5b88356147528161459d565b975060208901356147628161459d565b965060408901356147728161459d565b955060608901356147828161459d565b945060808901356147928161459d565b935060a089013592506147a88a60c08b016145c1565b91506101208901356001600160401b038111156147c3575f5ffd5b6147cf8b828c016146a2565b9150509295985092959890939650565b5f602082840312156147ef575f5ffd5b8135613b128161459d565b5f6020828403121561480a575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106145bc575f5ffd5b5f5f60408385031215614851575f5ffd5b61485a83614832565b946020939093013593505050565b5f60608284031215614878575f5ffd5b613b1283836145c1565b634e487b7160e01b5f52602160045260245ffd5b600e81106148a6576148a6614882565b9052565b602081016138428284614896565b600481106148a6576148a6614882565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614906602082018f6148b8565b8c60408201528b606082015261491f608082018c614811565b6101c060a08201525f6149366101c083018c6148c8565b82810360c0840152614948818c6148c8565b905061495760e084018b614811565b61496561010084018a614811565b876101208401528661014084015282810361016084015261498681876148c8565b915050614997610180830185614811565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156139af5781518452602093840193909101906001016149b6565b805182525f60208201516149ec60208501826148b8565b50604082015160408401526060820151614a0960608501826149b3565b50608082015160a084015260a0820151614a2660c0850182614811565b5060c082015161020060e0850152614a426102008501826148c8565b905060e0830151848203610100860152614a5c82826148c8565b915050610100830151614a73610120860182614811565b50610120830151614a88610140860182614811565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614aba82826148c8565b9150506101a0830151614ad16101c0860182614811565b506101c08301518015156101e0860152613a9a565b602081525f613b1260208301846149d5565b5f60208284031215614b08575f5ffd5b81356001600160401b03811115614b1d575f5ffd5b614b2984828501614637565b949350505050565b5f60208284031215614b41575f5ffd5b81356001600160401b03811115614b56575f5ffd5b82016101008185031215613b12575f5ffd5b828152604060208201525f614b2960408301846149d5565b5f60208284031215614b90575f5ffd5b81356001600160401b03811115614ba5575f5ffd5b614b29848285016146a2565b5f5f60408385031215614bc2575f5ffd5b823591506020830135614bd48161459d565b809150509250929050565b5f5f60408385031215614bf0575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101613842565b821515815260408101613b126020830184614896565b5f5f83601f840112614c46575f5ffd5b5081356001600160401b03811115614c5c575f5ffd5b602083019150836020828501011115613cc5575f5ffd5b5f5f5f5f5f60608688031215614c87575f5ffd5b8535945060208601356001600160401b03811115614ca3575f5ffd5b614caf88828901614c36565b90955093505060408601356001600160401b03811115614ccd575f5ffd5b614cd988828901614c36565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d4460e0840182614811565b50610100830151614d5c61010084018261ffff169052565b50610120830151614d7461012084018261ffff169052565b50610140830151614d8c61014084018261ffff169052565b50610160830151614da461016084018261ffff169052565b50610180830151614dbc61018084018261ffff169052565b506101a0830151614dd66101a084018263ffffffff169052565b506101c0830151614df06101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614e0d575f5ffd5b8735965060208801356001600160401b03811115614e29575f5ffd5b614e358a828b01614c36565b90975095505060408801356001600160401b03811115614e53575f5ffd5b614e5f8a828b01614c36565b90955093505060608801356001600160401b03811115614e7d575f5ffd5b614e898a828b01614c36565b989b979a50959850939692959293505050565b5f5f60408385031215614ead575f5ffd5b82359150602083013560ff81168114614bd4575f5ffd5b600781106148a6576148a6614882565b602081016138428284614ec4565b5f6101e0828403128015614ef4575f5ffd5b509092915050565b5f5f60608385031215614f0d575f5ffd5b614f1683614832565b915083606084011115614f27575f5ffd5b50926020919091019150565b600181811c90821680614f4757607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614f75575f5ffd5b613b1282614832565b634e487b7160e01b5f52603260045260245ffd5b6020810161384282846148b8565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561384257613842614fa0565b8082018082111561384257613842614fa0565b5f60018201614feb57614feb614fa0565b5060010190565b5f5f8335601e19843603018112615007575f5ffd5b8301803591506001600160401b03821115615020575f5ffd5b602001915036819003821315613cc5575f5ffd5b8015158114610d3f575f5ffd5b5f60208284031215615051575f5ffd5b8135613b1281615034565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6150a360a08301888a61505c565b82810360608401526150b681878961505c565b905082810360808401526150cb81858761505c565b9b9a5050505050505050505050565b5f602082840312156150ea575f5ffd5b5051919050565b601f821115613b3f57805f5260205f20601f840160051c810160208510156151165750805b601f840160051c820191505b81811015615135575f8155600101615122565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b03811115615169576151696145d1565b61517d816151778454614f33565b846150f1565b6020601f8211600181146151aa575f83156151985750848201515b6151a2848261513c565b855550615135565b5f84815260208120601f198516915b828110156151d957878501518255602094850194600190920191016151b9565b50848210156151f657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561523f57815163ffffffff1683526020928301929091019060010161521a565b505050949350505050565b5f6020828403121561525a575f5ffd5b8151613b1281615034565b604081016152738285614ec4565b613b126020830184614ec4565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156152ed57603f198786030184526152d88583516148c8565b945060209384019391909101906001016152bc565b50929695505050505050565b8381526060810161530d6020830185614ec4565b614b296040830184614ec4565b5f8151808452602084019350602083015f5b828110156153535781516001600160a01b031686526020958601959091019060010161532c565b5093949350505050565b848152836020820152608060408201525f61537b608083018561531a565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61440a60608301848661505c565b602081525f614b2960208301848661505c565b6001600160401b038311156153ec576153ec6145d1565b615400836153fa8354614f33565b836150f1565b5f601f84116001811461542c575f851561541a5750838201355b615424868261513c565b845550615135565b5f83815260208120601f198716915b8281101561545b578685013582556020948501946001909201910161543b565b5086821015615477575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6154a260608301868861505c565b82810360408401526154b581858761505c565b98975050505050505050565b604081525f6154d460408301868861505c565b82810360208401526154e781858761505c565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356145bc816154f2565b5f6020828403121561551c575f5ffd5b8135613b12816154f2565b63ffffffff81168114610d3f575f5ffd5b80356145bc81615527565b5f60208284031215615553575f5ffd5b8135613b1281615527565b5f81356138428161459d565b5f8135613842816154f2565b5f813561384281615527565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016155f26155d560e0850161555e565b82546001600160a01b0319166001600160a01b0391909116178255565b615622615602610100850161556a565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b615652615632610120850161556a565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b615682615662610140850161556a565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6156b2615692610160850161556a565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6156e26156c2610180850161556a565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161570e6156f76101a08501615576565b825463ffffffff191663ffffffff91909116178255565b613b3f61571e6101c08501615576565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161579160e084016145b1565b61579e60e0840182614811565b506157ac6101008401615501565b61ffff166101008301526157c36101208401615501565b61ffff166101208301526157da6101408401615501565b61ffff166101408301526157f16101608401615501565b61ffff166101608301526158086101808401615501565b61ffff1661018083015261581f6101a08401615538565b63ffffffff166101a08301526158386101c08401615538565b63ffffffff81166101c0840152614df0565b808202811582820484141761384257613842614fa0565b5f8261587b57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156158b757813561589c81615527565b63ffffffff1683526020928301929190910190600101615888565b50505092915050565b604081016158ce8285614ec4565b613b126020830184614896565b5f602082840312156158eb575f5ffd5b81516001600160401b03811115615900575f5ffd5b8201601f81018413615910575f5ffd5b805161591e6146bf82614615565b8082825260208201915060208360051b85010192508683111561593f575f5ffd5b6020840193505b8284101561440a5783516159598161459d565b825260209384019390910190615946565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f61599b606083018561531a565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156153535781518652602095860195909101906001016159c5565b6001600160a01b03841681526060602082018190525f90615a069083018561531a565b828103604084015261440a81856159b3565b604081525f615a2a604083018561531a565b8281036020840152615a3c81856159b3565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index b504fc1c46..35149dca85 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index c5ca800a4b..bf4d0a6cda 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -3,6 +3,154 @@ "contractName": "ICiphernodeRegistry", "sourceName": "contracts/interfaces/ICiphernodeRegistry.sol", "abi": [ + { + "inputs": [], + "name": "BondingRegistryNotSet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "node", + "type": "address" + } + ], + "name": "CiphernodeNotEnabled", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeAlreadyFinalized", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeAlreadyPublished", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeAlreadyRequested", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeDeadlineReached", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeNotFinalized", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeNotInitializedOrFinalized", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeNotPublished", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeNotRequested", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + } + ], + "name": "InsufficientCiphernodes", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTicketNumber", + "type": "error" + }, + { + "inputs": [], + "name": "NodeAlreadySubmitted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "node", + "type": "address" + } + ], + "name": "NodeNotBonded", + "type": "error" + }, + { + "inputs": [], + "name": "NodeNotEligible", + "type": "error" + }, + { + "inputs": [], + "name": "NodeNotSubmitted", + "type": "error" + }, + { + "inputs": [], + "name": "NotOwnerOrBondingRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "NotSlashingManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyBondingRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyEnclave", + "type": "error" + }, + { + "inputs": [], + "name": "SubmissionWindowClosed", + "type": "error" + }, + { + "inputs": [], + "name": "SubmissionWindowNotClosed", + "type": "error" + }, + { + "inputs": [], + "name": "ThresholdNotMet", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -806,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index cc7dba9dbd..9f95a33a78 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -3,6 +3,428 @@ "contractName": "IEnclave", "sourceName": "contracts/interfaces/IEnclave.sol", "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimum", + "type": "uint256" + } + ], + "name": "BelowMinCommitteeSize", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimum", + "type": "uint256" + } + ], + "name": "BelowMinThreshold", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "BpsExceedsMax", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "CiphertextOutputAlreadyPublished", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "CiphertextOutputNotPublished", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiration", + "type": "uint256" + } + ], + "name": "CommitteeDutiesCompleted", + "type": "error" + }, + { + "inputs": [], + "name": "CommitteeSelectionFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum IEnclave.CommitteeSize", + "name": "committeeSize", + "type": "uint8" + } + ], + "name": "CommitteeSizeNotConfigured", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum IEnclave.CommitteeSize", + "name": "committeeSize", + "type": "uint8" + } + ], + "name": "CommitteeSizeTooSmall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "E3AlreadyComplete", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "E3AlreadyFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "E3DoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "E3NotFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IE3Program", + "name": "e3Program", + "type": "address" + } + ], + "name": "E3ProgramNotAllowed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "FailureConditionNotMet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputDeadline", + "type": "uint256" + } + ], + "name": "InputDeadlineNotReached", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IBondingRegistry", + "name": "bondingRegistry", + "type": "address" + } + ], + "name": "InvalidBondingRegistry", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract ICiphernodeRegistry", + "name": "ciphernodeRegistry", + "type": "address" + } + ], + "name": "InvalidCiphernodeRegistry", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "encryptionSchemeId", + "type": "bytes32" + } + ], + "name": "InvalidEncryptionScheme", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "feeToken", + "type": "address" + } + ], + "name": "InvalidFeeToken", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "InvalidInputDeadline", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "InvalidInputDeadlineEnd", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + } + ], + "name": "InvalidInputDeadlineStart", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "output", + "type": "bytes" + } + ], + "name": "InvalidOutput", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + }, + { + "internalType": "enum IEnclave.E3Stage", + "name": "expected", + "type": "uint8" + }, + { + "internalType": "enum IEnclave.E3Stage", + "name": "actual", + "type": "uint8" + } + ], + "name": "InvalidStage", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidThresholdValues", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTimeoutWindow", + "type": "error" + }, + { + "inputs": [], + "name": "MinSizeBelowMinThreshold", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "ModuleAlreadyEnabled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "ModuleNotEnabled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "NoPaymentToRefund", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCiphernodeRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCiphernodeRegistryOrSlashingManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySlashingManager", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PaymentRequired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "PlaintextOutputAlreadyPublished", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + } + ], + "name": "ThresholdTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "TreasuryRequired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "UtilizationBpsExceedsMax", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -1671,5 +2093,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 3fb31bd749..152cd54269 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index a47fa2dfe4..acd5887045 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1309,5 +1309,5 @@ }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-440e5066adc51df4f47f79b4332765e96b80c6bb" + "buildInfoId": "solc-0_8_28-74ea8e366bd07fddf0065d16be962bc1ae5e80d7" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json b/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json index 433586d3fb..65becc23d6 100644 --- a/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json +++ b/packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json @@ -1223,5 +1223,5 @@ ] }, "inputSourceName": "project/contracts/token/EnclaveTicketToken.sol", - "buildInfoId": "solc-0_8_28-4e1d4326aa586bce7ef3b38a9e93aeff5ca3ac8f" + "buildInfoId": "solc-0_8_28-3f0df73226c7ff72a6c756321d5f230fe39ed6a0" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index 0e8ebfc57a..0945f27aaa 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -122,110 +122,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @notice Basis points denominator uint16 internal constant BPS_BASE = 10000; - //////////////////////////////////////////////////////////// - // // - // Errors // - // // - //////////////////////////////////////////////////////////// - - /// @notice Thrown when committee selection fails during E3 request or activation. - error CommitteeSelectionFailed(); - - /// @notice Thrown when an E3 request uses a program that is not enabled. - /// @param e3Program The E3 program address that is not allowed. - error E3ProgramNotAllowed(IE3Program e3Program); - - /// @notice Thrown when attempting to access an E3 that does not exist. - /// @param e3Id The ID of the non-existent E3. - error E3DoesNotExist(uint256 e3Id); - - /// @notice Thrown when attempting to enable a module or program that is already enabled. - /// @param module The address of the module that is already enabled. - error ModuleAlreadyEnabled(address module); - - /// @notice Thrown when attempting to disable a module or program that is not enabled. - /// @param module The address of the module that is not enabled. - error ModuleNotEnabled(address module); - - /// @notice Thrown when an invalid or disabled encryption scheme is used. - /// @param encryptionSchemeId The ID of the invalid encryption scheme. - error InvalidEncryptionScheme(bytes32 encryptionSchemeId); - - /// @notice Thrown when attempting to set an invalid ciphernode registry address. - /// @param ciphernodeRegistry The invalid ciphernode registry address. - error InvalidCiphernodeRegistry(ICiphernodeRegistry ciphernodeRegistry); - - /// @notice Thrown when the requested duration exceeds maxDuration or is zero. - /// @param duration The invalid duration value. - error InvalidDuration(uint256 duration); - - /// @notice Thrown when output verification fails. - /// @param output The invalid output data. - error InvalidOutput(bytes output); - - /// @notice Thrown when the committee size has not been configured with thresholds. - /// @param committeeSize The unconfigured committee size. - error CommitteeSizeNotConfigured(CommitteeSize committeeSize); - - /// @notice Thrown when attempting to publish ciphertext output that has already been published. - /// @param e3Id The ID of the E3. - error CiphertextOutputAlreadyPublished(uint256 e3Id); - - /// @notice Thrown when attempting to publish plaintext output before ciphertext output. - /// @param e3Id The ID of the E3. - error CiphertextOutputNotPublished(uint256 e3Id); - - /// @notice Thrown when payment is required but not provided or insufficient. - /// @param value The required payment amount. - error PaymentRequired(uint256 value); - - /// @notice Thrown when attempting to publish plaintext output that has already been published. - /// @param e3Id The ID of the E3. - error PlaintextOutputAlreadyPublished(uint256 e3Id); - - /// @notice Thrown when attempting to set an invalid bonding registry address. - /// @param bondingRegistry The invalid bonding registry address. - error InvalidBondingRegistry(IBondingRegistry bondingRegistry); - - /// @notice Thrown when attempting to set an invalid fee token address. - /// @param feeToken The invalid fee token address. - error InvalidFeeToken(IERC20 feeToken); - - /// @notice E3 is not in expected stage - error InvalidStage(uint256 e3Id, E3Stage expected, E3Stage actual); - - /// @notice E3 has already been marked as failed - error E3AlreadyFailed(uint256 e3Id); - - /// @notice E3 has already completed - error E3AlreadyComplete(uint256 e3Id); - - /// @notice Failure condition not yet met - error FailureConditionNotMet(uint256 e3Id); - - /// @notice The Input deadline is invalid - error InvalidInputDeadline(uint256 deadline); - - /// @notice The input deadline start is in the past - error InvalidInputDeadlineStart(uint256 start); - /// @notice The input deadline end is before the start - error InvalidInputDeadlineEnd(uint256 end); - - /// @notice Below minimum committee size - error CommitteeSizeTooSmall(CommitteeSize committeeSize); - /// @notice Below minimum threshold - error ThresholdTooSmall(uint256 threshold); - - /// @notice The duties are completed, and ciphernodes are not required to act anymore for this E3 - /// @param e3Id The ID of the E3 - /// @param expiration The expiration timestamp of the E3 - error CommitteeDutiesCompleted(uint256 e3Id, uint256 expiration); - - /// @notice The input deadline has not yet been reached - /// @param e3Id The ID of the E3 - /// @param inputDeadline The input deadline timestamp of the E3 - error InputDeadlineNotReached(uint256 e3Id, uint256 inputDeadline); - //////////////////////////////////////////////////////////// // // // Modifiers // @@ -236,7 +132,7 @@ contract Enclave is IEnclave, OwnableUpgradeable { modifier onlyCiphernodeRegistry() { require( msg.sender == address(ciphernodeRegistry), - "Only CiphernodeRegistry" + OnlyCiphernodeRegistry() ); _; } @@ -246,14 +142,14 @@ contract Enclave is IEnclave, OwnableUpgradeable { require( msg.sender == address(ciphernodeRegistry) || msg.sender == address(slashingManager), - "Only Registry or SlashingMgr" + OnlyCiphernodeRegistryOrSlashingManager() ); _; } /// @notice Restricts function to SlashingManager contract only modifier onlySlashingManager() { - require(msg.sender == address(slashingManager), "Only SlashingManager"); + require(msg.sender == address(slashingManager), OnlySlashingManager()); _; } @@ -560,6 +456,22 @@ contract Enclave is IEnclave, OwnableUpgradeable { return; } + // If all committee members were expelled (all malicious), refund the + // requester in full — the protocol should not profit from a + // compromised E3. + if (activeLength == 0) { + address requester = _e3Requesters[e3Id]; + if (requester != address(0)) { + paymentToken.safeTransfer(requester, totalAmount); + } + e3RefundManager.distributeSlashedFundsOnSuccess( + e3Id, + activeNodes, + paymentToken + ); + return; + } + // Split between protocol treasury and CN rewards uint256 protocolAmount = 0; uint16 _protocolShareBps = _e3ProtocolShareBps[e3Id]; @@ -575,19 +487,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { uint256 cnAmount = totalAmount - protocolAmount; - if (activeLength == 0) { - address requester = _e3Requesters[e3Id]; - if (requester != address(0) && cnAmount > 0) { - paymentToken.safeTransfer(requester, cnAmount); - } - e3RefundManager.distributeSlashedFundsOnSuccess( - e3Id, - activeNodes, - paymentToken - ); - return; - } - uint256[] memory amounts = new uint256[](activeLength); // Distribute CN share equally among active (non-expelled) committee members @@ -806,10 +705,10 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @param e3Id The ID of the failed E3 function processE3Failure(uint256 e3Id) external { E3Stage stage = _e3Stages[e3Id]; - require(stage == E3Stage.Failed, "E3 not failed"); + require(stage == E3Stage.Failed, E3NotFailed(e3Id)); uint256 payment = e3Payments[e3Id]; - require(payment > 0, "No payment to refund"); + require(payment > 0, NoPaymentToRefund(e3Id)); e3Payments[e3Id] = 0; // Prevent double processing address[] memory honestNodes = _getHonestNodes(e3Id); @@ -1044,9 +943,9 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @notice Internal function to set timeout config function _setTimeoutConfig(E3TimeoutConfig calldata config) internal { - require(config.dkgWindow > 0, "Invalid DKG window"); - require(config.computeWindow > 0, "Invalid compute window"); - require(config.decryptionWindow > 0, "Invalid decryption window"); + require(config.dkgWindow > 0, InvalidTimeoutWindow()); + require(config.computeWindow > 0, InvalidTimeoutWindow()); + require(config.decryptionWindow > 0, InvalidTimeoutWindow()); _timeoutConfig = config; @@ -1060,18 +959,21 @@ contract Enclave is IEnclave, OwnableUpgradeable { ) external onlyOwner { require( threshold[1] >= threshold[0] && threshold[0] > 0, - "Invalid threshold" + InvalidThresholdValues() ); // Enforce minimum committee bounds if configured PricingConfig memory pc = _pricingConfig; if (pc.minCommitteeSize > 0) { require( threshold[1] >= pc.minCommitteeSize, - "Below min committee size" + BelowMinCommitteeSize(threshold[1], pc.minCommitteeSize) ); } if (pc.minThreshold > 0) { - require(threshold[0] >= pc.minThreshold, "Below min threshold"); + require( + threshold[0] >= pc.minThreshold, + BelowMinThreshold(threshold[0], pc.minThreshold) + ); } committeeThresholds[size] = threshold; emit CommitteeThresholdsUpdated(size, threshold); @@ -1079,28 +981,31 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @inheritdoc IEnclave function setPricingConfig(PricingConfig calldata config) public onlyOwner { - require(config.marginBps <= BPS_BASE, "Margin exceeds 100%"); - require(config.protocolShareBps <= BPS_BASE, "Share exceeds 100%"); + require(config.marginBps <= BPS_BASE, BpsExceedsMax(config.marginBps)); + require( + config.protocolShareBps <= BPS_BASE, + BpsExceedsMax(config.protocolShareBps) + ); require( config.dkgUtilizationBps <= BPS_BASE, - "DKG utilization exceeds 100%" + UtilizationBpsExceedsMax(config.dkgUtilizationBps) ); require( config.computeUtilizationBps <= BPS_BASE, - "Compute utilization exceeds 100%" + UtilizationBpsExceedsMax(config.computeUtilizationBps) ); require( config.decryptUtilizationBps <= BPS_BASE, - "Decrypt utilization exceeds 100%" + UtilizationBpsExceedsMax(config.decryptUtilizationBps) ); require( config.protocolShareBps == 0 || config.protocolTreasury != address(0), - "Treasury required when protocol share > 0" + TreasuryRequired() ); require( config.minCommitteeSize >= config.minThreshold, - "Min size must be >= min threshold" + MinSizeBelowMinThreshold() ); _pricingConfig = config; emit PricingConfigUpdated(config); diff --git a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol index 34a113d6ba..e0b29b8e8d 100644 --- a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol @@ -168,6 +168,97 @@ interface ICiphernodeRegistry { /// @param sortitionSubmissionWindow The submission window for the E3 sortition in seconds. event SortitionSubmissionWindowSet(uint256 sortitionSubmissionWindow); + //////////////////////////////////////////////////////////// + // // + // Errors // + // // + //////////////////////////////////////////////////////////// + + /// @notice Committee has already been requested for this E3 + error CommitteeAlreadyRequested(); + + /// @notice Committee has already been published for this E3 + error CommitteeAlreadyPublished(); + + /// @notice Committee has not been published yet for this E3 + error CommitteeNotPublished(); + + /// @notice Committee has not been requested yet for this E3 + error CommitteeNotRequested(); + + /// @notice Committee Not Initialized or Finalized + error CommitteeNotInitializedOrFinalized(); + + /// @notice Submission Window has been closed for this E3 + error SubmissionWindowClosed(); + + /// @notice Committee deadline has been reached for this E3 + error CommitteeDeadlineReached(); + + /// @notice Committee has already been finalized for this E3 + error CommitteeAlreadyFinalized(); + + /// @notice Committee has not been finalized yet for this E3 + error CommitteeNotFinalized(); + + /// @notice Node has already submitted a ticket for this E3 + error NodeAlreadySubmitted(); + + /// @notice Node has not submitted a ticket for this E3 + error NodeNotSubmitted(); + + /// @notice Node is not eligible for this E3 + error NodeNotEligible(); + + /// @notice Ciphernode is not enabled in the registry + /// @param node Address of the ciphernode + error CiphernodeNotEnabled(address node); + + /// @notice Caller is not the Enclave contract + error OnlyEnclave(); + + /// @notice Caller is not the bonding registry + error OnlyBondingRegistry(); + + /// @notice Caller is neither owner nor bonding registry + error NotOwnerOrBondingRegistry(); + + /// @notice Node is not bonded + /// @param node Address of the node + error NodeNotBonded(address node); + + /// @notice Address cannot be zero + error ZeroAddress(); + + /// @notice Bonding registry has not been set + error BondingRegistryNotSet(); + + /// @notice Invalid ticket number + error InvalidTicketNumber(); + + /// @notice Submission window not closed yet + error SubmissionWindowNotClosed(); + + /// @notice Threshold not met for this E3 + error ThresholdNotMet(); + + /// @notice Caller is not authorized + error Unauthorized(); + + /// @notice Caller is not the slashing manager + error NotSlashingManager(); + + /// @notice Not enough registered ciphernodes to meet threshold + /// @param requested The requested committee size (N) + /// @param available The number of registered ciphernodes + error InsufficientCiphernodes(uint256 requested, uint256 available); + + //////////////////////////////////////////////////////////// + // // + // Function Signatures // + // // + //////////////////////////////////////////////////////////// + /// @notice Check if a ciphernode is eligible for committee selection /// @dev A ciphernode is eligible if it is enabled in the registry and meets bonding requirements /// @param ciphernode Address of the ciphernode to check diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index 6ea4b4fd52..0c64edf242 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -248,6 +248,159 @@ interface IEnclave { /// @notice Emitted when pricing configuration is updated event PricingConfigUpdated(PricingConfig config); + //////////////////////////////////////////////////////////// + // // + // Errors // + // // + //////////////////////////////////////////////////////////// + + /// @notice Thrown when committee selection fails during E3 request or activation. + error CommitteeSelectionFailed(); + + /// @notice Thrown when an E3 request uses a program that is not enabled. + /// @param e3Program The E3 program address that is not allowed. + error E3ProgramNotAllowed(IE3Program e3Program); + + /// @notice Thrown when attempting to access an E3 that does not exist. + /// @param e3Id The ID of the non-existent E3. + error E3DoesNotExist(uint256 e3Id); + + /// @notice Thrown when attempting to enable a module or program that is already enabled. + /// @param module The address of the module that is already enabled. + error ModuleAlreadyEnabled(address module); + + /// @notice Thrown when attempting to disable a module or program that is not enabled. + /// @param module The address of the module that is not enabled. + error ModuleNotEnabled(address module); + + /// @notice Thrown when an invalid or disabled encryption scheme is used. + /// @param encryptionSchemeId The ID of the invalid encryption scheme. + error InvalidEncryptionScheme(bytes32 encryptionSchemeId); + + /// @notice Thrown when attempting to set an invalid ciphernode registry address. + /// @param ciphernodeRegistry The invalid ciphernode registry address. + error InvalidCiphernodeRegistry(ICiphernodeRegistry ciphernodeRegistry); + + /// @notice Thrown when the requested duration exceeds maxDuration or is zero. + /// @param duration The invalid duration value. + error InvalidDuration(uint256 duration); + + /// @notice Thrown when output verification fails. + /// @param output The invalid output data. + error InvalidOutput(bytes output); + + /// @notice Thrown when the committee size has not been configured with thresholds. + /// @param committeeSize The unconfigured committee size. + error CommitteeSizeNotConfigured(CommitteeSize committeeSize); + + /// @notice Thrown when attempting to publish ciphertext output that has already been published. + /// @param e3Id The ID of the E3. + error CiphertextOutputAlreadyPublished(uint256 e3Id); + + /// @notice Thrown when attempting to publish plaintext output before ciphertext output. + /// @param e3Id The ID of the E3. + error CiphertextOutputNotPublished(uint256 e3Id); + + /// @notice Thrown when payment is required but not provided or insufficient. + /// @param value The required payment amount. + error PaymentRequired(uint256 value); + + /// @notice Thrown when attempting to publish plaintext output that has already been published. + /// @param e3Id The ID of the E3. + error PlaintextOutputAlreadyPublished(uint256 e3Id); + + /// @notice Thrown when attempting to set an invalid bonding registry address. + /// @param bondingRegistry The invalid bonding registry address. + error InvalidBondingRegistry(IBondingRegistry bondingRegistry); + + /// @notice Thrown when attempting to set an invalid fee token address. + /// @param feeToken The invalid fee token address. + error InvalidFeeToken(IERC20 feeToken); + + /// @notice E3 is not in expected stage + error InvalidStage(uint256 e3Id, E3Stage expected, E3Stage actual); + + /// @notice E3 has already been marked as failed + error E3AlreadyFailed(uint256 e3Id); + + /// @notice E3 has already completed + error E3AlreadyComplete(uint256 e3Id); + + /// @notice Failure condition not yet met + error FailureConditionNotMet(uint256 e3Id); + + /// @notice The Input deadline is invalid + error InvalidInputDeadline(uint256 deadline); + + /// @notice The input deadline start is in the past + error InvalidInputDeadlineStart(uint256 start); + + /// @notice The input deadline end is before the start + error InvalidInputDeadlineEnd(uint256 end); + + /// @notice Below minimum committee size + error CommitteeSizeTooSmall(CommitteeSize committeeSize); + + /// @notice Below minimum threshold + error ThresholdTooSmall(uint256 threshold); + + /// @notice The duties are completed, and ciphernodes are not required to act anymore for this E3 + /// @param e3Id The ID of the E3 + /// @param expiration The expiration timestamp of the E3 + error CommitteeDutiesCompleted(uint256 e3Id, uint256 expiration); + + /// @notice The input deadline has not yet been reached + /// @param e3Id The ID of the E3 + /// @param inputDeadline The input deadline timestamp of the E3 + error InputDeadlineNotReached(uint256 e3Id, uint256 inputDeadline); + + /// @notice Caller is not the CiphernodeRegistry + error OnlyCiphernodeRegistry(); + + /// @notice Caller is not the CiphernodeRegistry or SlashingManager + error OnlyCiphernodeRegistryOrSlashingManager(); + + /// @notice Caller is not the SlashingManager + error OnlySlashingManager(); + + /// @notice E3 is not in the Failed stage + /// @param e3Id The ID of the E3 + error E3NotFailed(uint256 e3Id); + + /// @notice No payment available to refund for this E3 + /// @param e3Id The ID of the E3 + error NoPaymentToRefund(uint256 e3Id); + + /// @notice Timeout window value is invalid (must be > 0) + error InvalidTimeoutWindow(); + + /// @notice Threshold values are invalid + error InvalidThresholdValues(); + + /// @notice Committee size is below the configured minimum + /// @param size The provided committee size + /// @param minimum The required minimum + error BelowMinCommitteeSize(uint256 size, uint256 minimum); + + /// @notice Threshold is below the configured minimum + /// @param threshold The provided threshold + /// @param minimum The required minimum + error BelowMinThreshold(uint256 threshold, uint256 minimum); + + /// @notice A basis-points value exceeds 100% (10000) + /// @param value The invalid BPS value + error BpsExceedsMax(uint256 value); + + /// @notice Protocol treasury address required when protocol share > 0 + error TreasuryRequired(); + + /// @notice Minimum committee size must be >= minimum threshold + error MinSizeBelowMinThreshold(); + + /// @notice Utilization BPS exceeds 100% + /// @param value The invalid utilization BPS value + error UtilizationBpsExceedsMax(uint256 value); + //////////////////////////////////////////////////////////// // // // Structs // diff --git a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol index 08935fce8e..305181ffbb 100644 --- a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol +++ b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol @@ -80,91 +80,6 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { /// @notice Address of the slashing manager authorized to expel committee members ISlashingManager public slashingManager; - //////////////////////////////////////////////////////////// - // // - // Errors // - // // - //////////////////////////////////////////////////////////// - - /// @notice Committee has already been requested for this E3 - error CommitteeAlreadyRequested(); - - /// @notice Committee has already been published for this E3 - error CommitteeAlreadyPublished(); - - /// @notice Committee has not been published yet for this E3 - error CommitteeNotPublished(); - - /// @notice Committee has not been requested yet for this E3 - error CommitteeNotRequested(); - - /// @notice Committee Not Initialized or Finalized - error CommitteeNotInitializedOrFinalized(); - - /// @notice Submission Window has been closed for this E3 - error SubmissionWindowClosed(); - - /// @notice Committee deadline has been reached for this E3 - error CommitteeDeadlineReached(); - - /// @notice Committee has already been finalized for this E3 - error CommitteeAlreadyFinalized(); - - /// @notice Committee has not been finalized yet for this E3 - error CommitteeNotFinalized(); - - /// @notice Node has already submitted a ticket for this E3 - error NodeAlreadySubmitted(); - - /// @notice Node has not submitted a ticket for this E3 - error NodeNotSubmitted(); - - /// @notice Node is not eligible for this E3 - error NodeNotEligible(); - - /// @notice Ciphernode is not enabled in the registry - /// @param node Address of the ciphernode - error CiphernodeNotEnabled(address node); - - /// @notice Caller is not the Enclave contract - error OnlyEnclave(); - - /// @notice Caller is not the bonding registry - error OnlyBondingRegistry(); - - /// @notice Caller is neither owner nor bonding registry - error NotOwnerOrBondingRegistry(); - - /// @notice Node is not bonded - /// @param node Address of the node - error NodeNotBonded(address node); - - /// @notice Address cannot be zero - error ZeroAddress(); - - /// @notice Bonding registry has not been set - error BondingRegistryNotSet(); - - /// @notice Invalid ticket number - error InvalidTicketNumber(); - - /// @notice Submission window not closed yet - error SubmissionWindowNotClosed(); - - /// @notice Threshold not met for this E3 - error ThresholdNotMet(); - - /// @notice Caller is not authorized - error Unauthorized(); - - /// @notice Caller is not the slashing manager - error NotSlashingManager(); - - /// @notice Not enough registered ciphernodes to meet threshold - /// @param requested The requested committee size (N) - /// @param available The number of registered ciphernodes - error InsufficientCiphernodes(uint256 requested, uint256 available); - //////////////////////////////////////////////////////////// // // // Modifiers // diff --git a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol index 6ba01456b8..ee3a608b60 100644 --- a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol @@ -176,8 +176,6 @@ contract MockCiphernodeRegistry is ICiphernodeRegistry { } contract MockCiphernodeRegistryEmptyKey is ICiphernodeRegistry { - error CommitteeNotPublished(); - function requestCommittee( uint256, uint256, diff --git a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts index b1faa93a65..d8eac31daa 100644 --- a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -558,8 +558,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await makeRequest(); // E3 is in Requested state, not Failed - await expect(enclave.processE3Failure(0)).to.be.revertedWith( - "E3 not failed", + await expect(enclave.processE3Failure(0)).to.be.revertedWithCustomError( + enclave, + "E3NotFailed", ); }); @@ -659,8 +660,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await enclave.processE3Failure(0); // Second call should fail - payment already cleared - await expect(enclave.processE3Failure(0)).to.be.revertedWith( - "No payment to refund", + await expect(enclave.processE3Failure(0)).to.be.revertedWithCustomError( + enclave, + "NoPaymentToRefund", ); }); diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index 518244d560..a4c5c2e4c9 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -528,7 +528,7 @@ describe("E3 Pricing", function () { const { enclave } = await loadFixture(setup); await expect( enclave.setPricingConfig({ ...defaultPricingConfig, marginBps: 10001 }), - ).to.be.revertedWith("Margin exceeds 100%"); + ).to.be.revertedWithCustomError(enclave, "BpsExceedsMax"); }); it("allows setting margin to 0", async function () { @@ -545,7 +545,7 @@ describe("E3 Pricing", function () { ...defaultPricingConfig, protocolShareBps: 10001, }), - ).to.be.revertedWith("Share exceeds 100%"); + ).to.be.revertedWithCustomError(enclave, "BpsExceedsMax"); }); it("reverts if minCommitteeSize < minThreshold", async function () { @@ -556,7 +556,7 @@ describe("E3 Pricing", function () { minCommitteeSize: 2, minThreshold: 5, }), - ).to.be.revertedWith("Min size must be >= min threshold"); + ).to.be.revertedWithCustomError(enclave, "MinSizeBelowMinThreshold"); }); it("enforces bounds on setCommitteeThresholds", async function () { @@ -572,12 +572,12 @@ describe("E3 Pricing", function () { // Should fail: committee size 4 < min 5 await expect( enclave.setCommitteeThresholds(0, [3, 4]), - ).to.be.revertedWith("Below min committee size"); + ).to.be.revertedWithCustomError(enclave, "BelowMinCommitteeSize"); // Should fail: threshold 2 < min 3 await expect( enclave.setCommitteeThresholds(0, [2, 6]), - ).to.be.revertedWith("Below min threshold"); + ).to.be.revertedWithCustomError(enclave, "BelowMinThreshold"); // Should succeed: meets both minimums await expect(enclave.setCommitteeThresholds(0, [3, 5])).to.not.be.revert(