diff --git a/Cargo.lock b/Cargo.lock index e5b31e5d0c..aa076f755c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3624,6 +3624,7 @@ dependencies = [ "e3-config", "e3-data", "e3-events", + "e3-fhe-params", "e3-utils", "serde", "tracing", diff --git a/crates/aggregator/src/ext.rs b/crates/aggregator/src/ext.rs index fd2b9cfbaa..d7712e8215 100644 --- a/crates/aggregator/src/ext.rs +++ b/crates/aggregator/src/ext.rs @@ -27,15 +27,11 @@ use e3_sortition::Sortition; pub struct PublicKeyAggregatorExtension { bus: BusHandle, - params_preset: BfvPreset, } impl PublicKeyAggregatorExtension { - pub fn create(bus: &BusHandle, params_preset: BfvPreset) -> Box { - Box::new(Self { - bus: bus.clone(), - params_preset, - }) + pub fn create(bus: &BusHandle) -> Box { + Box::new(Self { bus: bus.clone() }) } } @@ -66,6 +62,7 @@ impl E3Extension for PublicKeyAggregatorExtension { threshold_n, threshold_m, seed, + params_preset, .. } = data.clone(); let repo = ctx.repositories().publickey(&e3_id); @@ -80,7 +77,7 @@ impl E3Extension for PublicKeyAggregatorExtension { self.bus.clone(), e3_id, sync_state, - self.params_preset.clone(), + params_preset, ); ctx.set_event_recipient("publickey", Some(value)); @@ -109,12 +106,20 @@ impl E3Extension for PublicKeyAggregatorExtension { return Ok(()); }; + let Some(meta) = ctx.get_dependency(META_KEY) else { + self.bus.err( + EType::PublickeyAggregation, + anyhow!(ERROR_PUBKEY_META_MISSING), + ); + + return Ok(()); + }; let value = create_publickey_aggregator( fhe.clone(), self.bus.clone(), ctx.e3_id.clone(), sync_state, - self.params_preset.clone(), + meta.params_preset, ); // send to context @@ -151,19 +156,13 @@ fn create_publickey_aggregator( pub struct ThresholdPlaintextAggregatorExtension { bus: BusHandle, sortition: Addr, - params_preset: BfvPreset, } impl ThresholdPlaintextAggregatorExtension { - pub fn create( - bus: &BusHandle, - sortition: &Addr, - params_preset: BfvPreset, - ) -> Box { + pub fn create(bus: &BusHandle, sortition: &Addr) -> Box { Box::new(Self { bus: bus.clone(), sortition: sortition.clone(), - params_preset, }) } } @@ -213,7 +212,7 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { bus: self.bus.clone(), sortition: self.sortition.clone(), e3_id: e3_id.clone(), - params_preset: self.params_preset.clone(), + params_preset: meta.params_preset, }, sync_state, ) @@ -239,12 +238,20 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { return Ok(()); }; + let Some(meta) = ctx.get_dependency(META_KEY) else { + self.bus.err( + EType::PlaintextAggregation, + anyhow!(ERROR_TRBFV_PLAINTEXT_META_MISSING), + ); + + return Ok(()); + }; let value = ThresholdPlaintextAggregator::new( ThresholdPlaintextAggregatorParams { bus: self.bus.clone(), sortition: self.sortition.clone(), e3_id: ctx.e3_id.clone(), - params_preset: self.params_preset.clone(), + params_preset: meta.params_preset, }, sync_state, ) diff --git a/crates/ciphernode-builder/src/ciphernode_builder.rs b/crates/ciphernode-builder/src/ciphernode_builder.rs index 054965d17c..00c2b88008 100644 --- a/crates/ciphernode-builder/src/ciphernode_builder.rs +++ b/crates/ciphernode-builder/src/ciphernode_builder.rs @@ -23,7 +23,6 @@ use e3_evm::{ SlashingManagerSolWriter, }; use e3_fhe::ext::FheExtension; -use e3_fhe_params::{BfvPreset, DEFAULT_BFV_PRESET}; use e3_keyshare::ext::ThresholdKeyshareExtension; use e3_multithread::{Multithread, MultithreadReport, TaskPool}; use e3_net::{ @@ -466,11 +465,6 @@ impl CiphernodeBuilder { if let Some(KeyshareKind::Threshold) = self.keyshare { let _ = self.ensure_multithread(&bus); - // TODO: Make BfvPreset configurable via builder method (e.g., with_share_enc_preset()) - // Currently hardcoded to InsecureDkg512 for DKG operations. - // Production deployments should use BfvPreset::SecureDkg8192. - let share_enc_preset = BfvPreset::InsecureDkg512; - let backend = self .zk_backend .as_ref() @@ -486,7 +480,6 @@ impl CiphernodeBuilder { &bus, &self.cipher, &addr, - share_enc_preset, )); info!("Setting up ZK actors"); @@ -502,14 +495,7 @@ impl CiphernodeBuilder { info!("Setting up PublicKeyAggregationExtension"); // Ensure multithread worker is available for C1 verification and C5 proof generation let _ = self.ensure_multithread(&bus); - // TODO: Make BfvPreset configurable via builder method. - // Currently hardcoded to InsecureThreshold512 for C5 proof generation. - // Production deployments should use the appropriate threshold preset. - let aggregator_preset = DEFAULT_BFV_PRESET; - e3_builder = e3_builder.with(PublicKeyAggregatorExtension::create( - &bus, - aggregator_preset, - )); + e3_builder = e3_builder.with(PublicKeyAggregatorExtension::create(&bus)); if self.keyshare.is_none() { let backend = self @@ -525,11 +511,8 @@ impl CiphernodeBuilder { if self.threshold_plaintext_agg { info!("Setting up ThresholdPlaintextAggregatorExtension"); let _ = self.ensure_multithread(&bus); - let aggregator_preset = DEFAULT_BFV_PRESET; e3_builder = e3_builder.with(ThresholdPlaintextAggregatorExtension::create( - &bus, - &sortition, - aggregator_preset, + &bus, &sortition, )) } diff --git a/crates/events/src/enclave_event/ciphernode_selected.rs b/crates/events/src/enclave_event/ciphernode_selected.rs index d5b21c4e21..1ee333451f 100644 --- a/crates/events/src/enclave_event/ciphernode_selected.rs +++ b/crates/events/src/enclave_event/ciphernode_selected.rs @@ -6,6 +6,7 @@ use crate::{E3id, Seed}; use actix::Message; +use e3_fhe_params::BfvPreset; use e3_utils::utility_types::ArcBytes; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display}; @@ -19,6 +20,7 @@ pub struct CiphernodeSelected { pub seed: Seed, pub error_size: ArcBytes, pub esi_per_ct: usize, + pub params_preset: BfvPreset, pub params: ArcBytes, pub party_id: u64, } @@ -29,6 +31,7 @@ impl Default for CiphernodeSelected { e3_id: E3id::new("0", 0), error_size: ArcBytes::from_bytes(&[]), esi_per_ct: 0, + params_preset: BfvPreset::InsecureThreshold512, params: ArcBytes::from_bytes(&[]), party_id: 0, seed: Seed([0u8; 32]), diff --git a/crates/events/src/enclave_event/e3_requested.rs b/crates/events/src/enclave_event/e3_requested.rs index 9d1d471033..83b830ebe7 100644 --- a/crates/events/src/enclave_event/e3_requested.rs +++ b/crates/events/src/enclave_event/e3_requested.rs @@ -6,6 +6,7 @@ use crate::{E3id, Seed}; use actix::Message; +use e3_fhe_params::BfvPreset; use e3_utils::utility_types::ArcBytes; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display}; @@ -26,7 +27,11 @@ pub struct E3Requested { pub error_size: ArcBytes, /// The number of smudging noise per ciphertext. pub esi_per_ct: usize, - /// The FHE parameters + /// The threshold BFV preset selected on-chain. The DKG counterpart is + /// derived automatically via `BfvPreset::dkg_counterpart()`. + pub params_preset: BfvPreset, + /// ABI-encoded BFV parameters (derived from `params_preset`). + /// Kept for downstream code that needs the raw bytes (e.g. `TrBFVConfig`). pub params: ArcBytes, /// When true, ciphernodes generate wrapper/fold proofs for DKG proof /// aggregation (public verifiability). When false, wrapper/fold proofs @@ -45,6 +50,7 @@ impl Default for E3Requested { e3_id: E3id::new("99", 0), error_size: ArcBytes::from_bytes(&[]), esi_per_ct: 0, + params_preset: BfvPreset::InsecureThreshold512, params: ArcBytes::from_bytes(&[]), seed: Seed([0u8; 32]), threshold_m: 0, diff --git a/crates/evm-helpers/src/contracts.rs b/crates/evm-helpers/src/contracts.rs index 0546acaa45..8a0ae61fac 100644 --- a/crates/evm-helpers/src/contracts.rs +++ b/crates/evm-helpers/src/contracts.rs @@ -55,7 +55,7 @@ sol! { uint256[2] inputWindow; bytes32 encryptionSchemeId; address e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes customParams; address decryptionVerifier; address pkVerifier; @@ -71,7 +71,7 @@ sol! { CommitteeSize committeeSize; uint256[2] inputWindow; address e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes computeProviderParams; bytes customParams; bool proofAggregationEnabled; @@ -129,6 +129,7 @@ sol! { function publishCiphertextOutput(uint256 e3Id, bytes calldata ciphertextOutput, bytes calldata proof) external returns (bool success); function publishPlaintextOutput(uint256 e3Id, bytes calldata data, bytes calldata proof, bytes calldata foldProof) external returns (bool success); function getE3(uint256 e3Id) external view returns (E3 memory e3); + function paramSetRegistry(uint8 paramSet) external view returns (bytes memory encodedParams); function getE3Quote(E3RequestParams memory request) external view returns (uint256 fee); function getE3Stage(uint256 e3Id) external view returns (E3Stage stage); function getFailureReason(uint256 e3Id) external view returns (FailureReason reason); @@ -156,10 +157,10 @@ pub trait EnclaveRead { /// Get the fee quote for an E3 request async fn get_e3_quote( &self, - commitee_size: CommitteeSize, + committee_size: CommitteeSize, input_window: [U256; 2], e3_program: Address, - e3_params: Bytes, + param_set: u8, compute_provider_params: Bytes, proof_aggregation_enabled: bool, ) -> Result; @@ -173,6 +174,9 @@ pub trait EnclaveRead { async fn get_deadlines(&self, e3_id: U256) -> Result; async fn get_timeout_config(&self) -> Result; + + /// Look up the ABI-encoded BFV parameters for a param set index + async fn get_param_set_registry(&self, param_set: u8) -> Result; } /// Trait for write operations on the Enclave contract @@ -184,7 +188,7 @@ pub trait EnclaveWrite { committee_size: CommitteeSize, input_window: [U256; 2], e3_program: Address, - e3_params: Bytes, + param_set: u8, compute_provider_params: Bytes, custom_params: Bytes, proof_aggregation_enabled: bool, @@ -372,7 +376,7 @@ where committee_size: CommitteeSize, input_window: [U256; 2], e3_program: Address, - e3_params: Bytes, + param_set: u8, compute_provider_params: Bytes, proof_aggregation_enabled: bool, ) -> Result { @@ -380,7 +384,7 @@ where committeeSize: committee_size, inputWindow: input_window, e3Program: e3_program, - e3ProgramParams: e3_params, + paramSet: param_set, computeProviderParams: compute_provider_params, customParams: Bytes::new(), proofAggregationEnabled: proof_aggregation_enabled, @@ -420,6 +424,12 @@ where let config = contract.getTimeoutConfig().call().await?; Ok(config) } + + async fn get_param_set_registry(&self, param_set: u8) -> Result { + let contract = Enclave::new(self.contract_address, &self.provider); + let params = contract.paramSetRegistry(param_set).call().await?; + Ok(params) + } } // Implement EnclaveWrite only for contracts with ReadWrite marker @@ -430,7 +440,7 @@ impl EnclaveWrite for EnclaveContract { committee_size: CommitteeSize, input_window: [U256; 2], e3_program: Address, - e3_params: Bytes, + param_set: u8, compute_provider_params: Bytes, custom_params: Bytes, proof_aggregation_enabled: bool, @@ -448,7 +458,7 @@ impl EnclaveWrite for EnclaveContract { committeeSize: committee_size, inputWindow: input_window, e3Program: e3_program, - e3ProgramParams: e3_params.clone(), + paramSet: param_set, computeProviderParams: compute_provider_params.clone(), customParams: custom_params.clone(), proofAggregationEnabled: proof_aggregation_enabled, diff --git a/crates/evm-helpers/src/events.rs b/crates/evm-helpers/src/events.rs index b570fae253..0fd272e028 100644 --- a/crates/evm-helpers/src/events.rs +++ b/crates/evm-helpers/src/events.rs @@ -43,7 +43,7 @@ sol! { uint256[2] inputWindow; bytes32 encryptionSchemeId; IE3Program e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes customParams; IDecryptionVerifier decryptionVerifier; IPkVerifier pkVerifier; diff --git a/crates/evm-helpers/tests/fixtures/fake_enclave.sol b/crates/evm-helpers/tests/fixtures/fake_enclave.sol index dbe7649fce..61e2a0cf6f 100644 --- a/crates/evm-helpers/tests/fixtures/fake_enclave.sol +++ b/crates/evm-helpers/tests/fixtures/fake_enclave.sol @@ -12,6 +12,8 @@ contract FakeEnclave { event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); event CommitteePublished(uint256 indexed e3Id, address[] nodes, bytes publicKey, bytes proof); + mapping(uint8 => bytes) public paramSetRegistry; + // Emit InputPublished event with passed test data function emitInputPublished(uint256 e3Id, bytes memory data, uint256 inputHash, uint256 index) public { emit InputPublished(e3Id, data, inputHash, index); @@ -42,7 +44,7 @@ contract FakeEnclave { encryptionSchemeId: bytes32(keccak256("AES-256-GCM")), e3Program: 0x7F3E4df648B8Cb96C1D343be976b91B97CaD5c21, decryptionVerifier: 0x4B0D8c2E5f7a6c832f8b16d3aB0e7F5d9E9B24b1, - e3ProgramParams: abi.encode(42, "testParams"), + paramSet: 0, customParams: abi.encode("custom_params"), committeePublicKey: bytes32(keccak256("committee_public_key")), ciphertextOutput: bytes32(keccak256("encrypted_data")), @@ -58,7 +60,7 @@ struct E3 { uint256[2] inputWindow; bytes32 encryptionSchemeId; address e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes customParams; address decryptionVerifier; bytes32 committeePublicKey; diff --git a/crates/evm/src/enclave_sol_reader.rs b/crates/evm/src/enclave_sol_reader.rs index 78b0018bf5..b999276904 100644 --- a/crates/evm/src/enclave_sol_reader.rs +++ b/crates/evm/src/enclave_sol_reader.rs @@ -12,7 +12,7 @@ use alloy::{sol, sol_types::SolEvent}; use e3_events::E3id; use e3_events::EnclaveEventData; use e3_events::{E3Failed, E3Stage, E3StageChanged, FailureReason}; -use e3_fhe_params::decode_bfv_params_arc; +use e3_fhe_params::{encode_bfv_params, BfvParamSet, BfvPreset}; use e3_trbfv::helpers::calculate_error_size; use e3_utils::ArcBytes; use e3_zk_helpers::CiphernodesCommitteeSize; @@ -29,8 +29,6 @@ struct E3RequestedWithChainId(pub IEnclave::E3Requested, pub u64); impl E3RequestedWithChainId { fn try_into_e3_requested(self) -> anyhow::Result { - let params_bytes = self.0.e3.e3ProgramParams.to_vec(); - // Derive threshold values from committee size enum let committee_size = match self.0.e3.committeeSize { 0 => CiphernodesCommitteeSize::Micro, @@ -43,7 +41,16 @@ impl E3RequestedWithChainId { let threshold_m = committee.threshold; let threshold_n = committee.n; - let params_arc = decode_bfv_params_arc(¶ms_bytes).expect("Failed to decode BFV params"); + // Map on-chain ParamSet enum to BfvPreset + let param_set_value: u8 = self.0.e3.paramSet.try_into().map_err(|_| { + anyhow::anyhow!("ParamSet enum value too large: {}", self.0.e3.paramSet) + })?; + let params_preset = BfvPreset::from_on_chain_param_set(param_set_value) + .ok_or_else(|| anyhow::anyhow!("Unknown ParamSet enum value: {}", param_set_value))?; + + // Build BFV parameters from the preset + let params_arc = BfvParamSet::from(params_preset).build_arc(); + let params_bytes = encode_bfv_params(¶ms_arc); // TODO: These should be delivered from the e3_program contract // For now, using defaults that match the test configuration: @@ -52,12 +59,7 @@ impl E3RequestedWithChainId { let lambda = 2; let esi_per_ct = 3; - let error_size = match calculate_error_size( - params_arc.clone(), - threshold_n, - threshold_m, - lambda, - ) { + let error_size = match calculate_error_size(params_arc, threshold_n, threshold_m, lambda) { Ok(size) => { let size_bytes = size.to_bytes_be(); info!( @@ -79,6 +81,7 @@ impl E3RequestedWithChainId { }; Ok(e3_events::E3Requested { + params_preset, params: ArcBytes::from_bytes(¶ms_bytes), threshold_m, threshold_n, diff --git a/crates/fhe-params/src/presets.rs b/crates/fhe-params/src/presets.rs index 54f2e7b7d6..6bc3ec1ed4 100644 --- a/crates/fhe-params/src/presets.rs +++ b/crates/fhe-params/src/presets.rs @@ -58,6 +58,18 @@ pub enum BfvPreset { SecureDkg8192, } +impl BfvPreset { + /// Convert an on-chain `ParamSet` enum value (uint8) to the corresponding + /// threshold `BfvPreset`. Returns `None` for unknown values. + pub fn from_on_chain_param_set(value: u8) -> Option { + match value { + 0 => Some(BfvPreset::InsecureThreshold512), + 1 => Some(BfvPreset::SecureThreshold8192), + _ => None, + } + } +} + /// Default BFV preset used across the workspace. /// /// This is the canonical preset for production (secure threshold 8192). diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index f1757eb40e..62e6afcec4 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -344,6 +344,7 @@ impl EnclaveIndexer { ); let e3 = contract.get_e3(e.e3Id).await?; + let e3_params = contract.get_param_set_registry(e3.paramSet).await?; let seed = e3.seed.to_be_bytes(); let request_block = u64_try_from(e3.requestBlock)?; let input_window = [ @@ -357,7 +358,7 @@ impl EnclaveIndexer { ciphertext_output: vec![], committee_public_key: e.publicKey.to_vec(), custom_params: e3.customParams.to_vec(), - e3_params: e3.e3ProgramParams.to_vec(), + e3_params: e3_params.to_vec(), enclave_address, encryption_scheme_id: e3.encryptionSchemeId.to_vec(), id: e3_id, diff --git a/crates/indexer/tests/fixtures/fake_enclave.sol b/crates/indexer/tests/fixtures/fake_enclave.sol index 2ae26dc98c..0c306441e4 100644 --- a/crates/indexer/tests/fixtures/fake_enclave.sol +++ b/crates/indexer/tests/fixtures/fake_enclave.sol @@ -12,6 +12,8 @@ contract FakeEnclave { event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); event CommitteePublished(uint256 indexed e3Id, address[] nodes, bytes publicKey, bytes proof); + mapping(uint8 => bytes) public paramSetRegistry; + // Emit InputPublished event with passed test data function emitInputPublished(uint256 e3Id, bytes memory data, uint256 inputHash, uint256 index) public { emit InputPublished(e3Id, data, inputHash, index); @@ -43,7 +45,7 @@ contract FakeEnclave { e3Program: 0x7F3E4df648B8Cb96C1D343be976b91B97CaD5c21, decryptionVerifier: 0x4B0D8c2E5f7a6c832f8b16d3aB0e7F5d9E9B24b1, pkVerifier: 0x5C1e9D3f8A7B6c932F9C27e4Ab1F8F6e0F0C35c2, - e3ProgramParams: abi.encode(42, "testParams"), + paramSet: 0, customParams: abi.encode("custom_params"), committeePublicKey: bytes32(keccak256("committee_public_key")), ciphertextOutput: bytes32(keccak256("encrypted_data")), @@ -67,7 +69,7 @@ struct E3 { uint256[2] inputWindow; bytes32 encryptionSchemeId; address e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes customParams; address decryptionVerifier; address pkVerifier; diff --git a/crates/keyshare/src/ext.rs b/crates/keyshare/src/ext.rs index 4446f8203b..89e9f051a9 100644 --- a/crates/keyshare/src/ext.rs +++ b/crates/keyshare/src/ext.rs @@ -14,7 +14,6 @@ use async_trait::async_trait; use e3_crypto::Cipher; use e3_data::{AutoPersist, RepositoriesFactory}; use e3_events::{prelude::*, BusHandle, EType, EnclaveEvent, EnclaveEventData}; -use e3_fhe_params::BfvPreset; use e3_request::{E3Context, E3ContextSnapshot, E3Extension, META_KEY}; use crate::KeyshareState; @@ -23,21 +22,14 @@ pub struct ThresholdKeyshareExtension { bus: BusHandle, cipher: Arc, address: String, - share_enc_preset: BfvPreset, } impl ThresholdKeyshareExtension { - pub fn create( - bus: &BusHandle, - cipher: &Arc, - address: &str, - share_enc_preset: BfvPreset, - ) -> Box { + pub fn create(bus: &BusHandle, cipher: &Arc, address: &str) -> Box { Box::new(Self { bus: bus.clone(), cipher: cipher.to_owned(), address: address.to_owned(), - share_enc_preset, }) } } @@ -84,7 +76,10 @@ impl E3Extension for ThresholdKeyshareExtension { bus: self.bus.clone(), cipher: self.cipher.clone(), state: container, - share_enc_preset: self.share_enc_preset, + share_enc_preset: meta + .params_preset + .dkg_counterpart() + .unwrap_or(meta.params_preset), }) .start() .into(), @@ -109,12 +104,21 @@ impl E3Extension for ThresholdKeyshareExtension { return Ok(()); }; + // Derive DKG preset from persisted E3Meta + let Some(meta) = ctx.get_dependency(META_KEY) else { + return Err(anyhow!(ERROR_KEYSHARE_META_MISSING)); + }; + let share_enc_preset = meta + .params_preset + .dkg_counterpart() + .unwrap_or(meta.params_preset); + // Construct from snapshot let value = ThresholdKeyshare::new(ThresholdKeyshareParams { bus: self.bus.clone(), cipher: self.cipher.clone(), state, - share_enc_preset: self.share_enc_preset, + share_enc_preset, }) .start() .into(); diff --git a/crates/request/Cargo.toml b/crates/request/Cargo.toml index 440f66054a..422947311e 100644 --- a/crates/request/Cargo.toml +++ b/crates/request/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/gnosisguild/enclave/crates/request" [dependencies] actix = { workspace = true } e3-events = { workspace = true } +e3-fhe-params = { workspace = true } e3-data = { workspace = true} e3-utils = { workspace = true} anyhow = { workspace = true } diff --git a/crates/request/src/meta.rs b/crates/request/src/meta.rs index adf3646ce0..3aef30ff09 100644 --- a/crates/request/src/meta.rs +++ b/crates/request/src/meta.rs @@ -9,6 +9,7 @@ use anyhow::*; use async_trait::async_trait; use e3_data::RepositoriesFactory; use e3_events::{E3Requested, EnclaveEvent, EnclaveEventData, Event, Seed}; +use e3_fhe_params::BfvPreset; use e3_utils::utility_types::ArcBytes; pub const META_KEY: TypedKey = TypedKey::new("meta"); @@ -18,6 +19,7 @@ pub struct E3Meta { pub threshold_m: usize, pub threshold_n: usize, pub seed: Seed, + pub params_preset: BfvPreset, pub params: ArcBytes, pub esi_per_ct: usize, pub error_size: ArcBytes, @@ -43,6 +45,7 @@ impl E3Extension for E3MetaExtension { threshold_n, seed, e3_id, + params_preset, params, esi_per_ct, error_size, @@ -55,6 +58,7 @@ impl E3Extension for E3MetaExtension { threshold_m, threshold_n, seed, + params_preset, params, esi_per_ct, error_size, diff --git a/crates/sortition/src/ciphernode_selector.rs b/crates/sortition/src/ciphernode_selector.rs index 3c2cf247dd..daa436a911 100644 --- a/crates/sortition/src/ciphernode_selector.rs +++ b/crates/sortition/src/ciphernode_selector.rs @@ -31,6 +31,7 @@ fn e3_meta_from(req: &E3Requested) -> E3Meta { seed: req.seed, threshold_n: req.threshold_n, threshold_m: req.threshold_m, + params_preset: req.params_preset, params: req.params.clone(), esi_per_ct: req.esi_per_ct, error_size: req.error_size.clone(), @@ -311,6 +312,7 @@ impl Handler> for CiphernodeSelector { threshold_n: e3_meta.threshold_n, esi_per_ct: e3_meta.esi_per_ct, error_size: e3_meta.error_size.clone(), + params_preset: e3_meta.params_preset, params: e3_meta.params.clone(), seed: e3_meta.seed, }, diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index 882fe101a3..8cdfd6c383 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -887,6 +887,7 @@ async fn test_trbfv_actor() -> Result<()> { seed: seed.clone(), error_size, esi_per_ct: esi_per_ct as usize, + params_preset: DEFAULT_BFV_PRESET, params, proof_aggregation_enabled, }; diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index 221ee71ca3..0a33266823 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -3,23 +3,23 @@ chains: rpc_url: ws://localhost:8545 contracts: e3_program: - address: "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570" - deploy_block: 33 + address: "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + deploy_block: 32 enclave: address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - deploy_block: 15 + deploy_block: 14 ciphernode_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 11 + deploy_block: 10 bonding_registry: address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - deploy_block: 12 + deploy_block: 11 slashing_manager: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - deploy_block: 10 + deploy_block: 9 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - deploy_block: 6 + deploy_block: 5 program: dev: true # risc0: diff --git a/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockEnclave.sol b/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockEnclave.sol index 8ca678f8e9..cb9b37b441 100644 --- a/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockEnclave.sol +++ b/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockEnclave.sol @@ -27,7 +27,7 @@ contract MockEnclave { inputWindow: [uint256(0), uint256(0)], encryptionSchemeId: bytes32(0), e3Program: IE3Program(address(0)), - e3ProgramParams: bytes(""), + paramSet: 0, // Insecure512 customParams: abi.encode(address(0), nextE3Id, 2, 0, 0), decryptionVerifier: IDecryptionVerifier(address(0)), pkVerifier: IPkVerifier(address(0)), @@ -64,7 +64,7 @@ contract MockEnclave { inputWindow: [uint256(0), block.timestamp + 100], encryptionSchemeId: bytes32(0), e3Program: IE3Program(address(0)), - e3ProgramParams: bytes(""), + paramSet: 0, // Insecure512 customParams: abi.encode(address(0), 0, 2, 0, 0), decryptionVerifier: IDecryptionVerifier(address(0)), pkVerifier: IPkVerifier(address(0)), diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index 998491cfd6..bc26c7fda9 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -1,7 +1,7 @@ { "sepolia": { "PoseidonT3": { - "blockNumber": 10395682, + "blockNumber": 10538633, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { @@ -111,61 +111,61 @@ "address": "0xaa4d3F3d3482cbC51f013c7Eb1591BeD9e0187dc" }, "MockComputeProvider": { - "blockNumber": 10395672, - "address": "0x998749710fFB66F09565f6E9b213De2A682C0394" + "blockNumber": 10395623, + "address": "0x917961bF444FbaA90B3bd5A46097d7824823b805" }, "MockDecryptionVerifier": { - "blockNumber": 10395673, - "address": "0x79fcbaE7ffFA4D7EE5DBF29be284AcE20824F850" + "blockNumber": 10395624, + "address": "0x426e651f1e8a386d8F9B2d99C484d31726A0dE42" }, "MockE3Program": { - "blockNumber": 10395674, - "address": "0x6d255f8Bf699E4332c9A594F32bE1eC767321379" + "blockNumber": 10395625, + "address": "0xcE63E1EcAf3A7FeB69bA949d9Cd6681bB2C7eC88" }, "ZKTranscriptLib": { "blockNumber": 10395628, "address": "0xBf0A32A7D546944561a8773628e6c0036C16354C" - }, - "MockRISC0Verifier": { - "address": "0x1DdB8dc5d48CE8598bcb92759A33ab4350e85Ef5", - "blockNumber": 10395677 - }, - "HonkVerifier": { - "address": "0xD2c0428dF646c5DBa7bfFb2005378EBA67603783", - "blockNumber": 10395678 - }, - "CRISPProgram": { - "address": "0xb5172dED86714d302BC4434E54Dc010343580764", - "blockNumber": 10395678, + } + }, + "undefined": { + "PoseidonT3": { + "blockNumber": 3, + "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" + } + }, + "default": { + "MockUSDC": { "constructorArgs": { - "enclave": "0x450015E41E1F6b6AfaEbf598E32a8d02a368c0A0", - "verifierAddress": "0x1DdB8dc5d48CE8598bcb92759A33ab4350e85Ef5", - "honkVerifierAddress": "0xD2c0428dF646c5DBa7bfFb2005378EBA67603783", - "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" - } + "initialSupply": "1000000" + }, + "blockNumber": 1, + "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3" }, - "MockVotingToken": { - "address": "0xCF32Da38ac52BadbFb278bc070B738C37D09a1E0", - "blockNumber": 10395680 + "EnclaveToken": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 1, + "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3" } }, "localhost": { "PoseidonT3": { - "blockNumber": 5, + "blockNumber": 4, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 6, + "blockNumber": 5, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 7, + "blockNumber": 6, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { @@ -174,14 +174,14 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 9, + "blockNumber": 8, "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 10, + "blockNumber": 9, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "CiphernodeRegistryOwnable": { @@ -196,7 +196,7 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 11, + "blockNumber": 10, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "BondingRegistry": { @@ -218,7 +218,7 @@ "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 12, + "blockNumber": 11, "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { @@ -229,19 +229,16 @@ "e3RefundManager": "0x0000000000000000000000000000000000000001", "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "maxDuration": "2592000", - "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}", - "params": [ - "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000" - ] + "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" }, "proxyRecords": { - "initData": "0x01d12f1c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000", + "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 15, + "blockNumber": 14, "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "E3RefundManager": { @@ -257,70 +254,70 @@ "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, - "blockNumber": 17, + "blockNumber": 16, "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, "MockComputeProvider": { - "blockNumber": 19, - "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" + "blockNumber": 18, + "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" }, "MockDecryptionVerifier": { - "blockNumber": 20, - "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" + "blockNumber": 19, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" }, "MockPkVerifier": { - "blockNumber": 21, - "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + "blockNumber": 20, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" }, "MockE3Program": { - "blockNumber": 22, - "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" + "blockNumber": 21, + "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" }, "ZKTranscriptLib": { - "blockNumber": 24, - "address": "0x851356ae760d987E095750cCeb3bC6014560891C" + "blockNumber": 23, + "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" }, "RecursiveAggregationFoldVerifier": { - "blockNumber": 25, - "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" + "blockNumber": 24, + "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" }, "ThresholdDecryptedSharesAggregationVerifier": { - "blockNumber": 26, - "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" + "blockNumber": 25, + "address": "0x998abeb3E57409262aE5b751f60747921B33613E" }, "ThresholdPkAggregationVerifier": { - "blockNumber": 27, - "address": "0x998abeb3E57409262aE5b751f60747921B33613E" + "blockNumber": 26, + "address": "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49" }, "BfvDecryptionVerifier": { - "blockNumber": 28, - "address": "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49" + "blockNumber": 27, + "address": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528" }, "BfvPkVerifier": { - "blockNumber": 30, - "address": "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf" + "blockNumber": 29, + "address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF" }, "MockRISC0Verifier": { - "address": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf", - "blockNumber": 32 + "address": "0x9d4454B023096f34B160D6B654540c56A1F81688", + "blockNumber": 31 }, "HonkVerifier": { - "address": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", - "blockNumber": 33 + "address": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", + "blockNumber": 32 }, "CRISPProgram": { - "address": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", - "blockNumber": 33, + "address": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D", + "blockNumber": 32, "constructorArgs": { "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "verifierAddress": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf", - "honkVerifierAddress": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", + "verifierAddress": "0x9d4454B023096f34B160D6B654540c56A1F81688", + "honkVerifierAddress": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" } }, "MockVotingToken": { - "address": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029", - "blockNumber": 35 + "address": "0x1291Be112d480055DaFd8a610b7d1e203891C274", + "blockNumber": 34 } } } \ No newline at end of file diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index af56812859..e3d3929bfb 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -13,10 +13,10 @@ ETHERSCAN_API_KEY="" CRON_API_KEY=1234567890 # Based on Default Anvil Deployments (Only for testing) -ENCLAVE_ADDRESS="0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" -CIPHERNODE_REGISTRY_ADDRESS="0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" -E3_PROGRAM_ADDRESS="0x36C02dA8a0983159322a80FFE9F24b1acfF8B570" -FEE_TOKEN_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" +ENCLAVE_ADDRESS=0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e +FEE_TOKEN_ADDRESS=0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 +E3_PROGRAM_ADDRESS=0x809d550fca64d94Bd9F66E60752A544199cfAC3D +CIPHERNODE_REGISTRY_ADDRESS=0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 # E3 Config # Defines the time interval during which users can submit their inputs diff --git a/examples/CRISP/server/src/cli/commands.rs b/examples/CRISP/server/src/cli/commands.rs index a21ede01f4..a5f0461a82 100644 --- a/examples/CRISP/server/src/cli/commands.rs +++ b/examples/CRISP/server/src/cli/commands.rs @@ -139,7 +139,8 @@ pub async fn initialize_crisp_round( return Err(anyhow::anyhow!("Invalid committee size: {}", invalid).into()); } }; - let e3_params = Bytes::from(encode_bfv_params(&generate_bfv_parameters())); + // param_set 0 = InsecureThreshold512 (must match on-chain paramSetRegistry) + let param_set: u8 = 0; let compute_provider_params = ComputeProviderParams { name: CONFIG.e3_compute_provider_name.to_string(), parallel: CONFIG.e3_compute_provider_parallel, @@ -168,7 +169,7 @@ pub async fn initialize_crisp_round( committee_size.clone(), input_window, e3_program, - e3_params.clone(), + param_set, compute_provider_params_bytes.clone(), proof_aggregation_enabled, ) @@ -214,7 +215,7 @@ pub async fn initialize_crisp_round( committee_size, input_window, e3_program, - e3_params, + param_set, compute_provider_params_bytes, custom_params_bytes, proof_aggregation_enabled, diff --git a/examples/CRISP/server/src/server/routes/rounds.rs b/examples/CRISP/server/src/server/routes/rounds.rs index 4fda2d3612..765fa03cbf 100644 --- a/examples/CRISP/server/src/server/routes/rounds.rs +++ b/examples/CRISP/server/src/server/routes/rounds.rs @@ -223,7 +223,8 @@ pub async fn initialize_crisp_round( U256::from(window_start), U256::from(window_start + CONFIG.e3_duration), ]; - let e3_params = Bytes::from(params); + // param_set 0 = InsecureThreshold512 (must match on-chain paramSetRegistry) + let param_set: u8 = 0; let compute_provider_params = ComputeProviderParams { name: CONFIG.e3_compute_provider_name.clone(), parallel: CONFIG.e3_compute_provider_parallel, @@ -238,7 +239,7 @@ pub async fn initialize_crisp_round( committee_size, input_window, e3_program, - e3_params, + param_set, compute_provider_params, custom_params_bytes, proof_aggregation_enabled, diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index 19883b9329..2a34d6c780 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -473,19 +473,6 @@ "name": "UtilizationBpsExceedsMax", "type": "error" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes[]", - "name": "e3ProgramParams", - "type": "bytes[]" - } - ], - "name": "AllowedE3ProgramsParamsSet", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -652,19 +639,6 @@ "name": "E3ProgramEnabled", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes[]", - "name": "e3ProgramParams", - "type": "bytes[]" - } - ], - "name": "E3ProgramsParamsRemoved", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -720,9 +694,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -920,6 +894,25 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "encodedParams", + "type": "bytes" + } + ], + "name": "ParamSetRegistered", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1279,25 +1272,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" - } - ], - "name": "e3ProgramsParams", - "outputs": [ - { - "internalType": "bool", - "name": "allowed", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "e3RefundManager", @@ -1347,9 +1321,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1537,9 +1511,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1610,9 +1584,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1895,11 +1869,6 @@ "internalType": "struct IEnclave.E3TimeoutConfig", "name": "config", "type": "tuple" - }, - { - "internalType": "bytes[]", - "name": "_e3ProgramsParams", - "type": "bytes[]" } ], "name": "initialize", @@ -2014,6 +1983,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "name": "paramSetRegistry", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -2109,19 +2097,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "_e3ProgramsParams", - "type": "bytes[]" - } - ], - "name": "removeE3ProgramsParams", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "renounceOwnership", @@ -2149,9 +2124,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -2214,9 +2189,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -2329,19 +2304,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "_e3ProgramsParams", - "type": "bytes[]" - } - ], - "name": "setE3ProgramsParams", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -2381,6 +2343,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "encodedParams", + "type": "bytes" + } + ], + "name": "setParamSet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -2559,11 +2539,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615b04806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614729565b61095a565b005b6102f06103003660046147d9565b610ba1565b61032d6103133660046147fb565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061481f565b60405180910390f35b61032d6103513660046147fb565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614841565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046147d9565b610c89565b6102f06103b4366004614869565b610d2e565b6103db6103c73660046147fb565b5f908152600f602052604090205460ff1690565b60405161033a91906148ab565b6103fb6103f63660046147fb565b610d42565b60405161033a9e9d9c9b9a999897969594939291906148f7565b6104286104233660046147fb565b610f6c565b60405161033a9190614ae7565b6104546104433660046147fb565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614af9565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046147fb565b611269565b6102f06104c13660046147d9565b6112f8565b6104d96104d4366004614b32565b61138b565b60405161033a929190614b69565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614b81565b611be6565b6102f061052c366004614bb2565b611c7e565b6102f061053f3660046147fb565b611d07565b6102f0610552366004614be0565b611e06565b60015461032d906001600160a01b031681565b61032d611efa565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f28565b60405161033a9190614c00565b6102f06105ba3660046147fb565b611f6e565b61059f6105cd3660046147fb565b6120dc565b6105e56105e03660046147fb565b612135565b60405161033a929190614c21565b61032d6106013660046147fb565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614c74565b61215c565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ceb565b61032d61078e3660046147fb565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614df8565b6123f4565b6102f06107c9366004614b81565b612624565b6102f06107dc366004614e9d565b6126bb565b6102f06107ef3660046147d9565b612777565b6102f0610802366004614be0565b61281e565b6104906108153660046147d9565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614bb2565b6128db565b6102f06108533660046147fb565b61298e565b61087a6108663660046147fb565b5f908152600d602052604090205460ff1690565b60405161033a9190614ed5565b6102f0610895366004614ee3565b6129cb565b6104546108a8366004614b32565b612c58565b6102f06108bb3660046147d9565b6131dc565b6102f06108ce366004614efd565b613276565b60025461032d906001600160a01b031681565b6102f06108f43660046147d9565b613523565b6103db6109073660046147fb565b61355d565b6102f061091a3660046147d9565b6136f7565b61032d61092d3660046147fb565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046147d9565b61378f565b5f61096361381e565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a0333613848565b610a0c8861298e565b610a158c6136f7565b610a1e8b6131dc565b610a278a610ba1565b610a3089610c89565b610a3987613859565b610a4286612624565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611efa565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613523565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613916565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613916565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb919061481f565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d2390839061481f565b60405180910390a150565b610d36613916565b610d3f81613859565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990614f34565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590614f34565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90614f34565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f7461440e565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614883565b6003811115610fc257610fc2614883565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490614f34565b80601f016020809104026020016040519081016040528092919081815260200182805461106090614f34565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490614f34565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090614f34565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90614f34565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890614f34565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613916565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613916565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb919061481f565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d2390839061481f565b5f61139461440e565b5f6012816113a56020870187614f66565b60038111156113b6576113b6614883565b60038111156113c7576113c7614883565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f8160016002811061144557611445614f7f565b602002015163ffffffff1611845f0160208101906114639190614f66565b906114825760405163286c068d60e11b8152600401610bfb9190614f93565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f2426040890135614fb5565b6114fc9190614fc8565b6115069190614fc8565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016147d9565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016147d9565b9061158e5760405163295a6a6f60e11b8152600401610bfb919061481f565b505f61159986612c58565b60068054965090915085905f6115ae83614fdb565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506116899190890135614fc8565b5f878152600e60209081526040909120600101919091558186526116af90880188614f66565b856020019060038111156116c5576116c5614883565b908160038111156116d8576116d8614883565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016147d9565b6001600160a01b031660a086015261173b6080880188614ff3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261178390880188614ff3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d0906101008901908901615042565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613948565b5f6118316080890160608a016147d9565b6001600160a01b031663fefd9a8b888461184e60808d018d614ff3565b61185b60a08f018f614ff3565b8f8060c0019061186b9190614ff3565b6040518963ffffffff1660e01b815260040161188e989796959493929190615085565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906150db565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614883565b0217905550604082015181600201556060820151816003019060026119c892919061448b565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d9082615151565b5060e08201516008820190611a229082615151565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a9082615151565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615206565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b30919061524b565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016147d9565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614b69565b60405180910390a2885f516020615ad85f395f51905f525f6001604051611bbf929190615266565b60405180910390a250505050505050915091565b611bdb613916565b611be45f6139b5565b565b611bee613916565b80515f5b81811015611c4257600b838281518110611c0e57611c0e614f7f565b6020026020010151604051611c239190615281565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615297565b60405180910390a15050565b611c86613916565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d315760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff166001816006811115611d5657611d56614883565b14611d7b57816001826040516337e1404160e01b8152600401610bfb939291906152fa565b5f828152600d60205260409020805460ff19166002179055601554611da09042614fc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615ad85f395f51905f5260016002604051611dfa929190615266565b60405180910390a25050565b5f546001600160a01b03163314611e305760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e6057611e60614883565b14611e8557836002826040516337e1404160e01b8152600401610bfb939291906152fa565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615ad85f395f51905f5260026003604051611eec929190615266565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9357611f93614883565b148290611fb657604051637cb2d48360e11b8152600401610bfb91815260200190565b505f828152600c60205260409020548281611fe7576040516345ba89d560e11b8152600401610bfb91815260200190565b505f838152600c6020526040812081905561200184613a25565b5f858152601160205260409020546002549192506001600160a01b039081169161202e9183911685613b12565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061206490889087908790879060040161535e565b5f604051808303815f87803b15801561207b575f5ffd5b505af115801561208d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a073178484516040516120cd929190918252602082015260400190565b60405180910390a25050505050565b6120fd60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121528482613b3d565b9250925050915091565b5f5f61216787610f6c565b5f888152600d602052604090205490915060ff16600381600681111561218f5761218f614883565b14886003839091926121b7576040516337e1404160e01b8152600401610bfb939291906152fa565b5050505f888152600e602090815260409182902082516060810184528154815260018201549281018390526002909101549281019290925289904281101561221b576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50506060830151602001518990428111156122525760405163017e35e560e71b815260048101929092526024820152604401610bfb565b505061016083015189901561227d57604051637eb9cea960e11b8152600401610bfb91815260200190565b505f888860405161228f929190615395565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506122d19042614fc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf9061231e908d9085908c908c906004016153a4565b6020604051808303815f875af115801561233a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061235e919061524b565b945088888661238257604051632f9f8ab960e01b8152600401610bfb9291906153c3565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123b69291906153c3565b60405180910390a2895f516020615ad85f395f51905f52600360046040516123df929190615266565b60405180910390a25050505095945050505050565b5f5f6123ff89610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561242757612427614883565b148a60048390919261244f576040516337e1404160e01b8152600401610bfb939291906152fa565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124b2576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016124cf8a8c836153d6565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b604051612513929190615395565b6040519081900381206001600160e01b031960e084901b168252612541918c908c908c908c9060040161548a565b602060405180830381865afa15801561255c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612580919061524b565b93508989856125a457604051632f9f8ab960e01b8152600401610bfb9291906153c3565b50506125af8b613cc5565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b6040516125e594939291906154c2565b60405180910390a28a5f516020615ad85f395f51905f526004600560405161260e929190615266565b60405180910390a2505050979650505050505050565b61262c613916565b80515f5b8181101561268b576001600b84838151811061264e5761264e614f7f565b60200260200101516040516126639190615281565b908152604051908190036020019020805491151560ff19909216919091179055600101612630565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615297565b5f546001600160a01b03163314806126dd57506003546001600160a01b031633145b6126fa57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156127105750600d60ff821611155b6127555760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b612773828260ff16600d81111561276e5761276e614883565b614131565b5050565b61277f613916565b6001600160a01b0381166127d55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612849576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612893575f5ffd5b505af11580156128a5573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611dfa91815260200190565b6128e3613916565b6001600160a01b0381161580159061291457505f828152600960205260409020546001600160a01b03828116911614155b8290612936576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612996613916565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b6129d3613916565b6127106129e86101208301610100840161550d565b61ffff161115612a006101208301610100840161550d565b90612a25576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a3b6101408301610120840161550d565b61ffff161115612a536101408301610120840161550d565b90612a78576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a8e6101608301610140840161550d565b61ffff161115612aa66101608301610140840161550d565b90612acb57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612ae16101808301610160840161550d565b61ffff161115612af96101808301610160840161550d565b90612b1e57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612b346101a08301610180840161550d565b61ffff161115612b4c6101a08301610180840161550d565b90612b7157604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612b846101408201610120830161550d565b61ffff161580612bad57505f612ba1610100830160e084016147d9565b6001600160a01b031614155b612bca5760405163015f92ff60e51b815260040160405180910390fd5b612bdc6101e082016101c08301615544565b63ffffffff16612bf46101c083016101a08401615544565b63ffffffff161015612c19576040516392f55c6560e01b815260040160405180910390fd5b806018612c268282615583565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d239190615741565b5f80601281612c6a6020860186614f66565b6003811115612c7b57612c7b614883565b6003811115612c8c57612c8c614883565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612cb3579050505050505090505f81600160028110612d0a57612d0a614f7f565b602002015163ffffffff1611835f016020810190612d289190614f66565b90612d475760405163286c068d60e11b8152600401610bfb9190614f93565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612e72576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612e519190614f66565b90612e705760405163010b971d60e31b8152600401610bfb9190614f93565b505b6101c081015163ffffffff1615612ec1576101c081015184519063ffffffff9081169082161015612ebf57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b60408601356020870135811015612eee5760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f9161271091612f0c9161ffff169061584b565b612f169190615862565b61271061ffff1683610160015161ffff16601560010154612f37919061584b565b612f419190615862565b61271061ffff1684610140015161ffff1660155f0154612f61919061584b565b612f6b9190615862565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612fb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fdb91906150db565b612fe59190614fc8565b612fef9190614fb5565b612ff99190614fc8565b6130039190614fc8565b61300d9190614fc8565b90505f61301b600186614fb5565b61302690600261584b565b61303190600261584b565b61303c906006614fc8565b90505f85845f015161304e919061584b565b905081868560200151613061919061584b565b61306b919061584b565b6130759082614fc8565b905060018611156130bd57600261308d600188614fb5565b613097908861584b565b85604001516130a6919061584b565b6130b09190615862565b6130ba9082614fc8565b90505b81868560c001516130ce919061584b565b6130d8919061584b565b6130e29082614fc8565b9050828685606001516130f5919061584b565b6130ff919061584b565b6131099082614fc8565b905084846080015161311b919061584b565b6131259082614fc8565b9050600185111561316d57600261313d600187614fb5565b613147908761584b565b8560400151613156919061584b565b6131609190615862565b61316a9082614fc8565b90505b60a084015161317c9082614fc8565b610100850151909150612710906131979061ffff1682614fc8565b6131a1908361584b565b6131ab9190615862565b975087806131cf57604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b6131e4613916565b6001600160a01b0381161580159061320a57506001546001600160a01b03828116911614155b819061322a576040516320252f0b60e01b8152600401610bfb919061481f565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d2390839061481f565b61327e613916565b61328b6020820182615544565b63ffffffff166132a16040830160208401615544565b63ffffffff16101580156132c657505f6132be6020830183615544565b63ffffffff16115b6132e357604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c08301521561341c576101a081015163ffffffff166133cc6040840160208501615544565b63ffffffff1610156133e46040840160208501615544565b826101a00151909161341957604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610bfb565b50505b6101c081015163ffffffff1615613493576101c081015163ffffffff166134466020840184615544565b63ffffffff16101561345b6020840184615544565b826101c0015190916134905760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610bfb565b50505b8160125f8560038111156134a9576134a9614883565b60038111156134ba576134ba614883565b815260208101919091526040015f206134d49160026144c9565b508260038111156134e7576134e7614883565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516135169190615881565b60405180910390a2505050565b61352b613916565b6001600160a01b038116613554575f604051631e4fbdf760e01b8152600401610bfb919061481f565b610d3f816139b5565b5f818152600d602052604081205460ff168181600681111561358157613581614883565b036135a657826001826040516337e1404160e01b8152600401610bfb939291906152fa565b60058160068111156135ba576135ba614883565b036135db5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156135ef576135ef614883565b0361361057604051633de16e3560e11b815260048101849052602401610bfb565b5f61361b8483613b3d565b935090508061364057604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561368957613689614883565b0217905550835f516020615ad85f395f51905f528360066040516136ae929190615266565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516136e89291906158c1565b60405180910390a25050919050565b6136ff613916565b6001600160a01b0381161580159061372457505f546001600160a01b03828116911614155b8190613744576040516375ac4eb760e11b8152600401610bfb919061481f565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d2390839061481f565b6001600160a01b0381165f90815260076020526040902054819060ff16156137cb5760405163b29d459560e01b8152600401610bfb919061481f565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d2390839061481f565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b61385061428c565b610d3f816142b1565b80356138785760405163055f269d60e01b815260040160405180910390fd5b5f81602001351161389c5760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138c05760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b3361391f611efa565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb919061481f565b6040516001600160a01b0384811660248301528381166044830152606482018390526139af9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142b9565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a4d57613a4d614883565b1480613a6a5750600281600d811115613a6857613a68614883565b145b15613aa2575f5b604051908082528060200260200182016040528015613a9a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613b0857506040513d5f823e601f3d908101601f19168201604052613b059190810190615937565b60015b613a9a575f613a71565b613b3883846001600160a01b031663a9059cbb858560405160240161397d9291906159fc565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bdb91906150db565b90506001856006811115613bf157613bf1614883565b148015613bfd57508042115b15613c1057600180935093505050613cbe565b6002856006811115613c2457613c24614883565b148015613c315750815142115b15613c455760016003935093505050613cbe565b6003856006811115613c5957613c59614883565b148015613c695750816020015142115b15613c7d5760016006935093505050613cbe565b6004856006811115613c9157613c91614883565b148015613ca15750816040015142115b15613cb5576001600a935093505050613cbe565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613d0a573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d319190810190615937565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dd0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d9c90889088908690600401615a15565b5f604051808303815f87803b158015613db3575f5ffd5b505af1158015613dc5573d5f5f3e3d5ffd5b505050505050505050565b825f03613e71575f858152601060205260409020546001600160a01b03168015613e0857613e086001600160a01b0383168285613b12565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e3c90899089908790600401615a15565b5f604051808303815f87803b158015613e53575f5ffd5b505af1158015613e65573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613eb157506001600160a01b03811615155b15613eed57612710613ec761ffff84168761584b565b613ed19190615862565b92508215613eed57613eed6001600160a01b0385168285613b12565b5f613ef88487614fb5565b90505f876001600160401b03811115613f1357613f136145cb565b604051908082528060200260200182016040528015613f3c578160200160208202803683370190505b5090505f613f4a8984615862565b90505f805b8a811015613f895782848281518110613f6a57613f6a614f7f565b6020908102919091010152613f7f8383614fc8565b9150600101613f4f565b505f613f958286614fb5565b90508015613fd2578084613faa60018e614fb5565b81518110613fba57613fba614f7f565b60200260200101818151613fce9190614fc8565b9052505b600154613fec906001600160a01b038b811691168761431c565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161403093929190615a75565b5f604051808303815f87803b158015614047575f5ffd5b505af1158015614059573d5f5f3e3d5ffd5b505060015461407792506001600160a01b038c81169250165f61431c565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516140a9929190615aaa565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140f593929190615a15565b5f604051808303815f87803b15801561410c575f5ffd5b505af115801561411e573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561415557614155614883565b0361417a57826001826040516337e1404160e01b8152600401610bfb939291906152fa565b600581600681111561418e5761418e614883565b036141af5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156141c3576141c3614883565b036141e457604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561422d5761422d614883565b0217905550825f516020615ad85f395f51905f52826006604051614252929190615266565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516135169291906158c1565b6142946143ac565b611be457604051631afcd79f60e31b815260040160405180910390fd5b61352b61428c565b5f5f60205f8451602086015f885af1806142d8576040513d5f823e3d81fd5b50505f513d915081156142ef5780600114156142fc565b6001600160a01b0384163b155b156139af5783604051635274afe760e01b8152600401610bfb919061481f565b5f836001600160a01b031663095ea7b3848460405160240161433f9291906159fc565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061437884826143c5565b6139af576143a284856001600160a01b031663095ea7b3865f60405160240161397d9291906159fc565b6139af84826142b9565b5f6143b561381e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614404575081156143f65780600114614404565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614436614565565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156144b9579160200282015b828111156144b957825182559160200191906001019061449e565b506144c5929150614583565b5090565b6001830191839082156144b9579160200282015f5b8382111561452857833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144de565b80156145585782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614528565b50506144c5929150614583565b60405180604001604052806002906020820280368337509192915050565b5b808211156144c5575f8155600101614584565b6001600160a01b0381168114610d3f575f5ffd5b80356145b681614597565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614607576146076145cb565b604052919050565b5f6001600160401b03821115614627576146276145cb565b5060051b60200190565b5f82601f830112614640575f5ffd5b81356001600160401b03811115614659576146596145cb565b61466c601f8201601f19166020016145df565b818152846020838601011115614680575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126146ab575f5ffd5b81356146be6146b98261460f565b6145df565b8082825260208201915060208360051b8601019250858311156146df575f5ffd5b602085015b8381101561471f5780356001600160401b03811115614701575f5ffd5b614710886020838a0101614631565b845250602092830192016146e4565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614741575f5ffd5b883561474c81614597565b9750602089013561475c81614597565b9650604089013561476c81614597565b9550606089013561477c81614597565b9450608089013561478c81614597565b935060a089013592506147a28a60c08b016145bb565b91506101208901356001600160401b038111156147bd575f5ffd5b6147c98b828c0161469c565b9150509295985092959890939650565b5f602082840312156147e9575f5ffd5b81356147f481614597565b9392505050565b5f6020828403121561480b575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106145b6575f5ffd5b5f5f60408385031215614852575f5ffd5b61485b83614833565b946020939093013593505050565b5f60608284031215614879575f5ffd5b6147f483836145bb565b634e487b7160e01b5f52602160045260245ffd5b600e81106148a7576148a7614883565b9052565b602081016138428284614897565b600481106148a7576148a7614883565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614907602082018f6148b9565b8c60408201528b6060820152614920608082018c614812565b6101c060a08201525f6149376101c083018c6148c9565b82810360c0840152614949818c6148c9565b905061495860e084018b614812565b61496661010084018a614812565b876101208401528661014084015282810361016084015261498781876148c9565b915050614998610180830185614812565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156139af5781518452602093840193909101906001016149b7565b805182525f60208201516149ed60208501826148b9565b50604082015160408401526060820151614a0a60608501826149b4565b50608082015160a084015260a0820151614a2760c0850182614812565b5060c082015161020060e0850152614a436102008501826148c9565b905060e0830151848203610100860152614a5d82826148c9565b915050610100830151614a74610120860182614812565b50610120830151614a89610140860182614812565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614abb82826148c9565b9150506101a0830151614ad26101c0860182614812565b506101c08301518015156101e0860152613a9a565b602081525f6147f460208301846149d6565b5f60208284031215614b09575f5ffd5b81356001600160401b03811115614b1e575f5ffd5b614b2a84828501614631565b949350505050565b5f60208284031215614b42575f5ffd5b81356001600160401b03811115614b57575f5ffd5b820161010081850312156147f4575f5ffd5b828152604060208201525f614b2a60408301846149d6565b5f60208284031215614b91575f5ffd5b81356001600160401b03811115614ba6575f5ffd5b614b2a8482850161469c565b5f5f60408385031215614bc3575f5ffd5b823591506020830135614bd581614597565b809150509250929050565b5f5f60408385031215614bf1575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101613842565b8215158152604081016147f46020830184614897565b5f5f83601f840112614c47575f5ffd5b5081356001600160401b03811115614c5d575f5ffd5b602083019150836020828501011115613cbe575f5ffd5b5f5f5f5f5f60608688031215614c88575f5ffd5b8535945060208601356001600160401b03811115614ca4575f5ffd5b614cb088828901614c37565b90955093505060408601356001600160401b03811115614cce575f5ffd5b614cda88828901614c37565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d4560e0840182614812565b50610100830151614d5d61010084018261ffff169052565b50610120830151614d7561012084018261ffff169052565b50610140830151614d8d61014084018261ffff169052565b50610160830151614da561016084018261ffff169052565b50610180830151614dbd61018084018261ffff169052565b506101a0830151614dd76101a084018263ffffffff169052565b506101c0830151614df16101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614e0e575f5ffd5b8735965060208801356001600160401b03811115614e2a575f5ffd5b614e368a828b01614c37565b90975095505060408801356001600160401b03811115614e54575f5ffd5b614e608a828b01614c37565b90955093505060608801356001600160401b03811115614e7e575f5ffd5b614e8a8a828b01614c37565b989b979a50959850939692959293505050565b5f5f60408385031215614eae575f5ffd5b82359150602083013560ff81168114614bd5575f5ffd5b600781106148a7576148a7614883565b602081016138428284614ec5565b5f6101e0828403128015614ef5575f5ffd5b509092915050565b5f5f60608385031215614f0e575f5ffd5b614f1783614833565b915083606084011115614f28575f5ffd5b50926020919091019150565b600181811c90821680614f4857607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614f76575f5ffd5b6147f482614833565b634e487b7160e01b5f52603260045260245ffd5b6020810161384282846148b9565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561384257613842614fa1565b8082018082111561384257613842614fa1565b5f60018201614fec57614fec614fa1565b5060010190565b5f5f8335601e19843603018112615008575f5ffd5b8301803591506001600160401b03821115615021575f5ffd5b602001915036819003821315613cbe575f5ffd5b8015158114610d3f575f5ffd5b5f60208284031215615052575f5ffd5b81356147f481615035565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6150a460a08301888a61505d565b82810360608401526150b781878961505d565b905082810360808401526150cc81858761505d565b9b9a5050505050505050505050565b5f602082840312156150eb575f5ffd5b5051919050565b601f821115613b3857805f5260205f20601f840160051c810160208510156151175750805b601f840160051c820191505b81811015615136575f8155600101615123565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b0381111561516a5761516a6145cb565b61517e816151788454614f34565b846150f2565b6020601f8211600181146151ab575f83156151995750848201515b6151a3848261513d565b855550615136565b5f84815260208120601f198516915b828110156151da57878501518255602094850194600190920191016151ba565b50848210156151f757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561524057815163ffffffff1683526020928301929091019060010161521b565b505050949350505050565b5f6020828403121561525b575f5ffd5b81516147f481615035565b604081016152748285614ec5565b6147f46020830184614ec5565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156152ee57603f198786030184526152d98583516148c9565b945060209384019391909101906001016152bd565b50929695505050505050565b8381526060810161530e6020830185614ec5565b614b2a6040830184614ec5565b5f8151808452602084019350602083015f5b828110156153545781516001600160a01b031686526020958601959091019060010161532d565b5093949350505050565b848152836020820152608060408201525f61537c608083018561531b565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61440460608301848661505d565b602081525f614b2a60208301848661505d565b6001600160401b038311156153ed576153ed6145cb565b615401836153fb8354614f34565b836150f2565b5f601f84116001811461542d575f851561541b5750838201355b615425868261513d565b845550615136565b5f83815260208120601f198716915b8281101561545c578685013582556020948501946001909201910161543c565b5086821015615478575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6154a360608301868861505d565b82810360408401526154b681858761505d565b98975050505050505050565b604081525f6154d560408301868861505d565b82810360208401526154e881858761505d565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356145b6816154f3565b5f6020828403121561551d575f5ffd5b81356147f4816154f3565b63ffffffff81168114610d3f575f5ffd5b80356145b681615528565b5f60208284031215615554575f5ffd5b81356147f481615528565b5f813561384281614597565b5f8135613842816154f3565b5f813561384281615528565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016155f36155d660e0850161555f565b82546001600160a01b0319166001600160a01b0391909116178255565b615623615603610100850161556b565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b615653615633610120850161556b565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b615683615663610140850161556b565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6156b3615693610160850161556b565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6156e36156c3610180850161556b565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161570f6156f86101a08501615577565b825463ffffffff191663ffffffff91909116178255565b613b3861571f6101c08501615577565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161579260e084016145ab565b61579f60e0840182614812565b506157ad6101008401615502565b61ffff166101008301526157c46101208401615502565b61ffff166101208301526157db6101408401615502565b61ffff166101408301526157f26101608401615502565b61ffff166101608301526158096101808401615502565b61ffff166101808301526158206101a08401615539565b63ffffffff166101a08301526158396101c08401615539565b63ffffffff81166101c0840152614df1565b808202811582820484141761384257613842614fa1565b5f8261587c57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156158b857813561589d81615528565b63ffffffff1683526020928301929190910190600101615889565b50505092915050565b604081016158cf8285614ec5565b6147f46020830184614897565b5f82601f8301126158eb575f5ffd5b81516158f96146b98261460f565b8082825260208201915060208360051b86010192508583111561591a575f5ffd5b602085015b8381101561471f57805183526020928301920161591f565b5f5f60408385031215615948575f5ffd5b82516001600160401b0381111561595d575f5ffd5b8301601f8101851361596d575f5ffd5b805161597b6146b98261460f565b8082825260208201915060208360051b85010192508783111561599c575f5ffd5b6020840193505b828410156159c75783516159b681614597565b8252602093840193909101906159a3565b8095505050505060208301516001600160401b038111156159e6575f5ffd5b6159f2858286016158dc565b9150509250929050565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615a2d606083018561531b565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615354578151865260209586019590910190600101615a57565b6001600160a01b03841681526060602082018190525f90615a989083018561531b565b82810360408401526144048185615a45565b604081525f615abc604083018561531b565b8281036020840152615ace8185615a45565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102d9575f3560e01c80639117173c11610182578063cb649617116100e0578063ea71aa571161008f578063ea71aa57146108c0578063f0691cba146108d3578063f2fde38b146108e6578063f81b8ef6146108f9578063fad8e1111461090c578063fbdb32371461091f578063fd2f3d0114610947575f5ffd5b8063cb64961714610829578063cbd1687214610832578063cf0f34c414610845578063cfbdc98d14610858578063d8afed3e14610887578063da16fb2f1461089a578063e59e4695146108ad575f5ffd5b8063ac3d2f421161013c578063ac3d2f4214610780578063b27392d5146107a8578063b68fd1be146107bb578063bb2d1b82146107ce578063bff232c1146107e1578063c1ab0f1f146107f4578063c4ccafa214610807575f5ffd5b80639117173c146105ac57806392312386146105bf578063929a8faf146105d257806399c6679d146105f35780639c8570c81461061b578063a87f4ab91461062e575f5ffd5b80634fc772641161023a5780637cfa9d74116101e95780637cfa9d741461053157806381476ec21461054457806385814243146105575780638da5cb5b1461056a5780638dcdd86b146105725780638e5ce3ad1461058457806390173a4114610597575f5ffd5b80634fc77264146104b357806364226409146104c6578063647846a5146104e75780636db5c8fd146104fa578063715018a61461050357806377868ae41461050b5780637c8c3b4d1461051e575f5ffd5b80631ba72945116102965780631ba72945146103a657806336c5d38a146103b95780634017daf0146103e8578063406ed35c146104155780634147a36014610435578063459d9294146104625780634e92ec63146104a0575f5ffd5b806301d12f1c146102dd57806302a3a9c9146102f25780630ef81b2f1461030557806310bc62811461034357806311bd61d91461036b57806315cce22414610393575b5f5ffd5b6102f06102eb366004614729565b61095a565b005b6102f06103003660046147d9565b610ba1565b61032d6103133660046147fb565b5f908152600960205260409020546001600160a01b031690565b60405161033a919061481f565b60405180910390f35b61032d6103513660046147fb565b60096020525f90815260409020546001600160a01b031681565b61037e610379366004614841565b610c4d565b60405163ffffffff909116815260200161033a565b6102f06103a13660046147d9565b610c89565b6102f06103b4366004614869565b610d2e565b6103db6103c73660046147fb565b5f908152600f602052604090205460ff1690565b60405161033a91906148ab565b6103fb6103f63660046147fb565b610d42565b60405161033a9e9d9c9b9a999897969594939291906148f7565b6104286104233660046147fb565b610f6c565b60405161033a9190614ae7565b6104546104433660046147fb565b600c6020525f908152604090205481565b60405190815260200161033a565b610490610470366004614af9565b8051602081830181018051600b8252928201919093012091525460ff1681565b604051901515815260200161033a565b6102f06104ae3660046147fb565b611269565b6102f06104c13660046147d9565b6112f8565b6104d96104d4366004614b32565b61138b565b60405161033a929190614b69565b60045461032d906001600160a01b031681565b61045460055481565b6102f0611bd3565b6102f0610519366004614b81565b611be6565b6102f061052c366004614bb2565b611c7e565b6102f061053f3660046147fb565b611d07565b6102f0610552366004614be0565b611e06565b60015461032d906001600160a01b031681565b61032d611efa565b5f5461032d906001600160a01b031681565b60035461032d906001600160a01b031681565b61059f611f28565b60405161033a9190614c00565b6102f06105ba3660046147fb565b611f6e565b61059f6105cd3660046147fb565b6120dc565b6105e56105e03660046147fb565b612135565b60405161033a929190614c21565b61032d6106013660046147fb565b5f908152601060205260409020546001600160a01b031690565b610490610629366004614c74565b61215c565b610773604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161033a9190614ceb565b61032d61078e3660046147fb565b5f908152600a60205260409020546001600160a01b031690565b6104906107b6366004614df8565b6123f4565b6102f06107c9366004614b81565b612624565b6102f06107dc366004614e9d565b6126bb565b6102f06107ef3660046147d9565b612777565b6102f0610802366004614be0565b61281e565b6104906108153660046147d9565b60076020525f908152604090205460ff1681565b61045460065481565b6102f0610840366004614bb2565b6128db565b6102f06108533660046147fb565b61298e565b61087a6108663660046147fb565b5f908152600d602052604090205460ff1690565b60405161033a9190614ed5565b6102f0610895366004614ee3565b6129cb565b6104546108a8366004614b32565b612c58565b6102f06108bb3660046147d9565b6131dc565b6102f06108ce366004614efd565b613276565b60025461032d906001600160a01b031681565b6102f06108f43660046147d9565b613523565b6103db6109073660046147fb565b61355d565b6102f061091a3660046147d9565b6136f7565b61032d61092d3660046147fb565b600a6020525f90815260409020546001600160a01b031681565b6102f06109553660046147d9565b61378f565b5f61096361381e565b805490915060ff600160401b82041615906001600160401b03165f811580156109895750825b90505f826001600160401b031660011480156109a45750303b155b9050811580156109b2575080155b156109d05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156109fa57845460ff60401b1916600160401b1785555b610a0333613848565b610a0c8861298e565b610a158c6136f7565b610a1e8b6131dc565b610a278a610ba1565b610a3089610c89565b610a3987613859565b610a4286612624565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff19169055610b2b611efa565b6001600160a01b03168d6001600160a01b031614610b4c57610b4c8d613523565b8315610b9257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b610ba9613916565b6001600160a01b038116610c045760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610c66575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610c91613916565b6001600160a01b03811615801590610cb757506004546001600160a01b03828116911614155b8190610cd75760405163eddf07f560e01b8152600401610bfb919061481f565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610d2390839061481f565b60405180910390a150565b610d36613916565b610d3f81613859565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610d8d90614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610db990614f34565b8015610e045780601f10610ddb57610100808354040283529160200191610e04565b820191905f5260205f20905b815481529060010190602001808311610de757829003601f168201915b505050505090806008018054610e1990614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4590614f34565b8015610e905780601f10610e6757610100808354040283529160200191610e90565b820191905f5260205f20905b815481529060010190602001808311610e7357829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610ecf90614f34565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90614f34565b8015610f465780601f10610f1d57610100808354040283529160200191610f46565b820191905f5260205f20905b815481529060010190602001808311610f2957829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610f7461440e565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610fb157610fb1614883565b6003811115610fc257610fc2614883565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610fe75750505091835250506005820154602082015260068201546001600160a01b0316604082015260078201805460609092019161103490614f34565b80601f016020809104026020016040519081016040528092919081815260200182805461106090614f34565b80156110ab5780601f10611082576101008083540402835291602001916110ab565b820191905f5260205f20905b81548152906001019060200180831161108e57829003601f168201915b505050505081526020016008820180546110c490614f34565b80601f01602080910402602001604051908101604052809291908181526020018280546110f090614f34565b801561113b5780601f106111125761010080835404028352916020019161113b565b820191905f5260205f20905b81548152906001019060200180831161111e57829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a09092019161118c90614f34565b80601f01602080910402602001604051908101604052809291908181526020018280546111b890614f34565b80156112035780601f106111da57610100808354040283529160200191611203565b820191905f5260205f20905b8154815290600101906020018083116111e657829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166112635760405163cd6f4a4f60e01b8152600401610bfb91815260200190565b50919050565b611271613916565b5f8181526009602052604090205481906001600160a01b03166112aa576040516381c4951960e01b8152600401610bfb91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610d239083815260200190565b611300613916565b6001600160a01b0381165f90815260076020526040902054819060ff1661133b576040516321ac7c5f60e01b8152600401610bfb919061481f565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610d2390839061481f565b5f61139461440e565b5f6012816113a56020870187614f66565b60038111156113b6576113b6614883565b60038111156113c7576113c7614883565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113ee579050505050505090505f8160016002811061144557611445614f7f565b602002015163ffffffff1611845f0160208101906114639190614f66565b906114825760405163286c068d60e11b8152600401610bfb9190614f93565b506020840135428110156114ac57604051630b99e87960e01b8152600401610bfb91815260200190565b50604084013560208501358110156114da5760405163174b5a0760e21b8152600401610bfb91815260200190565b506017546016545f91906114f2426040890135614fb5565b6114fc9190614fc8565b6115069190614fc8565b90506005548110819061152f576040516313b783af60e21b8152600401610bfb91815260200190565b5060075f61154360808801606089016147d9565b6001600160a01b0316815260208101919091526040015f205460ff1661156f60808701606088016147d9565b9061158e5760405163295a6a6f60e11b8152600401610bfb919061481f565b505f61159986612c58565b60068054965090915085905f6115ae83614fdb565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506116899190890135614fc8565b5f878152600e60209081526040909120600101919091558186526116af90880188614f66565b856020019060038111156116c5576116c5614883565b908160038111156116d8576116d8614883565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261172090608089019089016147d9565b6001600160a01b031660a086015261173b6080880188614ff3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c08087019190915261178390880188614ff3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526117d0906101008901908901615042565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611820916001600160a01b03909116903085613948565b5f6118316080890160608a016147d9565b6001600160a01b031663fefd9a8b888461184e60808d018d614ff3565b61185b60a08f018f614ff3565b8f8060c0019061186b9190614ff3565b6040518963ffffffff1660e01b815260040161188e989796959493929190615085565b6020604051808303815f875af11580156118aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce91906150db565b5f818152600960205260409020549091506001600160a01b0316818161190a576040516381c4951960e01b8152600401610bfb91815260200190565b505f828152600a60205260409020546001600160a01b03168281611944576040516381c4951960e01b8152600401610bfb91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff1991909116908360038111156119a2576119a2614883565b0217905550604082015181600201556060820151816003019060026119c892919061448b565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611a0d9082615151565b5060e08201516008820190611a229082615151565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d820190611a8a9082615151565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611af0908c9088908c90600401615206565b6020604051808303815f875af1158015611b0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b30919061524b565b611b4d57604051630d8dbe2560e01b815260040160405180910390fd5b611b5d60808b0160608c016147d9565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a604051611b97929190614b69565b60405180910390a2885f516020615ad85f395f51905f525f6001604051611bbf929190615266565b60405180910390a250505050505050915091565b611bdb613916565b611be45f6139b5565b565b611bee613916565b80515f5b81811015611c4257600b838281518110611c0e57611c0e614f7f565b6020026020010151604051611c239190615281565b908152604051908190036020019020805460ff19169055600101611bf2565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db82604051611c729190615297565b60405180910390a15050565b611c86613916565b6001600160a01b03811615801590611cb757505f828152600a60205260409020546001600160a01b03828116911614155b8290611cd9576040516381c4951960e01b8152600401610bfb91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611d315760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff166001816006811115611d5657611d56614883565b14611d7b57816001826040516337e1404160e01b8152600401610bfb939291906152fa565b5f828152600d60205260409020805460ff19166002179055601554611da09042614fc8565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615ad85f395f51905f5260016002604051611dfa929190615266565b60405180910390a25050565b5f546001600160a01b03163314611e305760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611e6057611e60614883565b14611e8557836002826040516337e1404160e01b8152600401610bfb939291906152fa565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615ad85f395f51905f5260026003604051611eec929190615266565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611f4960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f9357611f93614883565b148290611fb657604051637cb2d48360e11b8152600401610bfb91815260200190565b505f828152600c60205260409020548281611fe7576040516345ba89d560e11b8152600401610bfb91815260200190565b505f838152600c6020526040812081905561200184613a25565b5f858152601160205260409020546002549192506001600160a01b039081169161202e9183911685613b12565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061206490889087908790879060040161535e565b5f604051808303815f87803b15801561207b575f5ffd5b505af115801561208d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a073178484516040516120cd929190918252602082015260400190565b60405180910390a25050505050565b6120fd60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166121528482613b3d565b9250925050915091565b5f5f61216787610f6c565b5f888152600d602052604090205490915060ff16600381600681111561218f5761218f614883565b14886003839091926121b7576040516337e1404160e01b8152600401610bfb939291906152fa565b5050505f888152600e602090815260409182902082516060810184528154815260018201549281018390526002909101549281019290925289904281101561221b576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50506060830151602001518990428111156122525760405163017e35e560e71b815260048101929092526024820152604401610bfb565b505061016083015189901561227d57604051637eb9cea960e11b8152600401610bfb91815260200190565b505f888860405161228f929190615395565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556017549091506122d19042614fc8565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf9061231e908d9085908c908c906004016153a4565b6020604051808303815f875af115801561233a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061235e919061524b565b945088888661238257604051632f9f8ab960e01b8152600401610bfb9291906153c3565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516123b69291906153c3565b60405180910390a2895f516020615ad85f395f51905f52600360046040516123df929190615266565b60405180910390a25050505095945050505050565b5f5f6123ff89610f6c565b5f8a8152600d602052604090205490915060ff16600481600681111561242757612427614883565b148a60048390919261244f576040516337e1404160e01b8152600401610bfb939291906152fa565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b90428110156124b2576040516308f3034360e31b815260048101929092526024820152604401610bfb565b50505f8b8152600860205260409020600d016124cf8a8c836153d6565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b604051612513929190615395565b6040519081900381206001600160e01b031960e084901b168252612541918c908c908c908c9060040161548a565b602060405180830381865afa15801561255c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612580919061524b565b93508989856125a457604051632f9f8ab960e01b8152600401610bfb9291906153c3565b50506125af8b613cc5565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b6040516125e594939291906154c2565b60405180910390a28a5f516020615ad85f395f51905f526004600560405161260e929190615266565b60405180910390a2505050979650505050505050565b61262c613916565b80515f5b8181101561268b576001600b84838151811061264e5761264e614f7f565b60200260200101516040516126639190615281565b908152604051908190036020019020805491151560ff19909216919091179055600101612630565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be8182604051611c729190615297565b5f546001600160a01b03163314806126dd57506003546001600160a01b031633145b6126fa57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156127105750600d60ff821611155b6127555760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610bfb565b612773828260ff16600d81111561276e5761276e614883565b614131565b5050565b61277f613916565b6001600160a01b0381166127d55760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610bfb565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612849576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612893575f5ffd5b505af11580156128a5573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611dfa91815260200190565b6128e3613916565b6001600160a01b0381161580159061291457505f828152600960205260409020546001600160a01b03828116911614155b8290612936576040516381c4951960e01b8152600401610bfb91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb699101611c72565b612996613916565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610d23565b6129d3613916565b6127106129e86101208301610100840161550d565b61ffff161115612a006101208301610100840161550d565b90612a25576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a3b6101408301610120840161550d565b61ffff161115612a536101408301610120840161550d565b90612a78576040516301027fc160e21b815261ffff9091166004820152602401610bfb565b50612710612a8e6101608301610140840161550d565b61ffff161115612aa66101608301610140840161550d565b90612acb57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612ae16101808301610160840161550d565b61ffff161115612af96101808301610160840161550d565b90612b1e57604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612710612b346101a08301610180840161550d565b61ffff161115612b4c6101a08301610180840161550d565b90612b7157604051633239953960e01b815261ffff9091166004820152602401610bfb565b50612b846101408201610120830161550d565b61ffff161580612bad57505f612ba1610100830160e084016147d9565b6001600160a01b031614155b612bca5760405163015f92ff60e51b815260040160405180910390fd5b612bdc6101e082016101c08301615544565b63ffffffff16612bf46101c083016101a08401615544565b63ffffffff161015612c19576040516392f55c6560e01b815260040160405180910390fd5b806018612c268282615583565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610d239190615741565b5f80601281612c6a6020860186614f66565b6003811115612c7b57612c7b614883565b6003811115612c8c57612c8c614883565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612cb3579050505050505090505f81600160028110612d0a57612d0a614f7f565b602002015163ffffffff1611835f016020810190612d289190614f66565b90612d475760405163286c068d60e11b8152600401610bfb9190614f93565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115612e72576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190612e519190614f66565b90612e705760405163010b971d60e31b8152600401610bfb9190614f93565b505b6101c081015163ffffffff1615612ec1576101c081015184519063ffffffff9081169082161015612ebf57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610bfb565b505b60408601356020870135811015612eee5760405163174b5a0760e21b8152600401610bfb91815260200190565b506101808101516017545f9161271091612f0c9161ffff169061584b565b612f169190615862565b61271061ffff1683610160015161ffff16601560010154612f37919061584b565b612f419190615862565b61271061ffff1684610140015161ffff1660155f0154612f61919061584b565b612f6b9190615862565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612fb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fdb91906150db565b612fe59190614fc8565b612fef9190614fb5565b612ff99190614fc8565b6130039190614fc8565b61300d9190614fc8565b90505f61301b600186614fb5565b61302690600261584b565b61303190600261584b565b61303c906006614fc8565b90505f85845f015161304e919061584b565b905081868560200151613061919061584b565b61306b919061584b565b6130759082614fc8565b905060018611156130bd57600261308d600188614fb5565b613097908861584b565b85604001516130a6919061584b565b6130b09190615862565b6130ba9082614fc8565b90505b81868560c001516130ce919061584b565b6130d8919061584b565b6130e29082614fc8565b9050828685606001516130f5919061584b565b6130ff919061584b565b6131099082614fc8565b905084846080015161311b919061584b565b6131259082614fc8565b9050600185111561316d57600261313d600187614fb5565b613147908761584b565b8560400151613156919061584b565b6131609190615862565b61316a9082614fc8565b90505b60a084015161317c9082614fc8565b610100850151909150612710906131979061ffff1682614fc8565b6131a1908361584b565b6131ab9190615862565b975087806131cf57604051638c4fcd9360e01b8152600401610bfb91815260200190565b5050505050505050919050565b6131e4613916565b6001600160a01b0381161580159061320a57506001546001600160a01b03828116911614155b819061322a576040516320252f0b60e01b8152600401610bfb919061481f565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610d2390839061481f565b61327e613916565b61328b6020820182615544565b63ffffffff166132a16040830160208401615544565b63ffffffff16101580156132c657505f6132be6020830183615544565b63ffffffff16115b6132e357604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c08301521561341c576101a081015163ffffffff166133cc6040840160208501615544565b63ffffffff1610156133e46040840160208501615544565b826101a00151909161341957604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610bfb565b50505b6101c081015163ffffffff1615613493576101c081015163ffffffff166134466020840184615544565b63ffffffff16101561345b6020840184615544565b826101c0015190916134905760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610bfb565b50505b8160125f8560038111156134a9576134a9614883565b60038111156134ba576134ba614883565b815260208101919091526040015f206134d49160026144c9565b508260038111156134e7576134e7614883565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa836040516135169190615881565b60405180910390a2505050565b61352b613916565b6001600160a01b038116613554575f604051631e4fbdf760e01b8152600401610bfb919061481f565b610d3f816139b5565b5f818152600d602052604081205460ff168181600681111561358157613581614883565b036135a657826001826040516337e1404160e01b8152600401610bfb939291906152fa565b60058160068111156135ba576135ba614883565b036135db5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156135ef576135ef614883565b0361361057604051633de16e3560e11b815260048101849052602401610bfb565b5f61361b8483613b3d565b935090508061364057604051639f65d93560e01b815260048101859052602401610bfb565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561368957613689614883565b0217905550835f516020615ad85f395f51905f528360066040516136ae929190615266565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516136e89291906158c1565b60405180910390a25050919050565b6136ff613916565b6001600160a01b0381161580159061372457505f546001600160a01b03828116911614155b8190613744576040516375ac4eb760e11b8152600401610bfb919061481f565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610d2390839061481f565b6001600160a01b0381165f90815260076020526040902054819060ff16156137cb5760405163b29d459560e01b8152600401610bfb919061481f565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610d2390839061481f565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b61385061428c565b610d3f816142b1565b80356138785760405163055f269d60e01b815260040160405180910390fd5b5f81602001351161389c5760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138c05760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610d23565b3361391f611efa565b6001600160a01b031614611be4573360405163118cdaa760e01b8152600401610bfb919061481f565b6040516001600160a01b0384811660248301528381166044830152606482018390526139af9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142b9565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a4d57613a4d614883565b1480613a6a5750600281600d811115613a6857613a68614883565b145b15613aa2575f5b604051908082528060200260200182016040528015613a9a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613b0857506040513d5f823e601f3d908101601f19168201604052613b059190810190615937565b60015b613a9a575f613a71565b613b3883846001600160a01b031663a9059cbb858560405160240161397d9291906159fc565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bb7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bdb91906150db565b90506001856006811115613bf157613bf1614883565b148015613bfd57508042115b15613c1057600180935093505050613cbe565b6002856006811115613c2457613c24614883565b148015613c315750815142115b15613c455760016003935093505050613cbe565b6003856006811115613c5957613c59614883565b148015613c695750816020015142115b15613c7d5760016006935093505050613cbe565b6004856006811115613c9157613c91614883565b148015613ca15750816040015142115b15613cb5576001600a935093505050613cbe565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613d0a573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d319190810190615937565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dd0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d9c90889088908690600401615a15565b5f604051808303815f87803b158015613db3575f5ffd5b505af1158015613dc5573d5f5f3e3d5ffd5b505050505050505050565b825f03613e71575f858152601060205260409020546001600160a01b03168015613e0857613e086001600160a01b0383168285613b12565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e3c90899089908790600401615a15565b5f604051808303815f87803b158015613e53575f5ffd5b505af1158015613e65573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613eb157506001600160a01b03811615155b15613eed57612710613ec761ffff84168761584b565b613ed19190615862565b92508215613eed57613eed6001600160a01b0385168285613b12565b5f613ef88487614fb5565b90505f876001600160401b03811115613f1357613f136145cb565b604051908082528060200260200182016040528015613f3c578160200160208202803683370190505b5090505f613f4a8984615862565b90505f805b8a811015613f895782848281518110613f6a57613f6a614f7f565b6020908102919091010152613f7f8383614fc8565b9150600101613f4f565b505f613f958286614fb5565b90508015613fd2578084613faa60018e614fb5565b81518110613fba57613fba614f7f565b60200260200101818151613fce9190614fc8565b9052505b600154613fec906001600160a01b038b811691168761431c565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b815260040161403093929190615a75565b5f604051808303815f87803b158015614047575f5ffd5b505af1158015614059573d5f5f3e3d5ffd5b505060015461407792506001600160a01b038c81169250165f61431c565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d866040516140a9929190615aaa565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140f593929190615a15565b5f604051808303815f87803b15801561410c575f5ffd5b505af115801561411e573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561415557614155614883565b0361417a57826001826040516337e1404160e01b8152600401610bfb939291906152fa565b600581600681111561418e5761418e614883565b036141af5760405163462c7bed60e01b815260048101849052602401610bfb565b60068160068111156141c3576141c3614883565b036141e457604051633de16e3560e11b815260048101849052602401610bfb565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561422d5761422d614883565b0217905550825f516020615ad85f395f51905f52826006604051614252929190615266565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb82846040516135169291906158c1565b6142946143ac565b611be457604051631afcd79f60e31b815260040160405180910390fd5b61352b61428c565b5f5f60205f8451602086015f885af1806142d8576040513d5f823e3d81fd5b50505f513d915081156142ef5780600114156142fc565b6001600160a01b0384163b155b156139af5783604051635274afe760e01b8152600401610bfb919061481f565b5f836001600160a01b031663095ea7b3848460405160240161433f9291906159fc565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061437884826143c5565b6139af576143a284856001600160a01b031663095ea7b3865f60405160240161397d9291906159fc565b6139af84826142b9565b5f6143b561381e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015614404575081156143f65780600114614404565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614436614565565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156144b9579160200282015b828111156144b957825182559160200191906001019061449e565b506144c5929150614583565b5090565b6001830191839082156144b9579160200282015f5b8382111561452857833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144de565b80156145585782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614528565b50506144c5929150614583565b60405180604001604052806002906020820280368337509192915050565b5b808211156144c5575f8155600101614584565b6001600160a01b0381168114610d3f575f5ffd5b80356145b681614597565b919050565b5f60608284031215611263575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614607576146076145cb565b604052919050565b5f6001600160401b03821115614627576146276145cb565b5060051b60200190565b5f82601f830112614640575f5ffd5b81356001600160401b03811115614659576146596145cb565b61466c601f8201601f19166020016145df565b818152846020838601011115614680575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126146ab575f5ffd5b81356146be6146b98261460f565b6145df565b8082825260208201915060208360051b8601019250858311156146df575f5ffd5b602085015b8381101561471f5780356001600160401b03811115614701575f5ffd5b614710886020838a0101614631565b845250602092830192016146e4565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215614741575f5ffd5b883561474c81614597565b9750602089013561475c81614597565b9650604089013561476c81614597565b9550606089013561477c81614597565b9450608089013561478c81614597565b935060a089013592506147a28a60c08b016145bb565b91506101208901356001600160401b038111156147bd575f5ffd5b6147c98b828c0161469c565b9150509295985092959890939650565b5f602082840312156147e9575f5ffd5b81356147f481614597565b9392505050565b5f6020828403121561480b575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106145b6575f5ffd5b5f5f60408385031215614852575f5ffd5b61485b83614833565b946020939093013593505050565b5f60608284031215614879575f5ffd5b6147f483836145bb565b634e487b7160e01b5f52602160045260245ffd5b600e81106148a7576148a7614883565b9052565b602081016138428284614897565b600481106148a7576148a7614883565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614907602082018f6148b9565b8c60408201528b6060820152614920608082018c614812565b6101c060a08201525f6149376101c083018c6148c9565b82810360c0840152614949818c6148c9565b905061495860e084018b614812565b61496661010084018a614812565b876101208401528661014084015282810361016084015261498781876148c9565b915050614998610180830185614812565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156139af5781518452602093840193909101906001016149b7565b805182525f60208201516149ed60208501826148b9565b50604082015160408401526060820151614a0a60608501826149b4565b50608082015160a084015260a0820151614a2760c0850182614812565b5060c082015161020060e0850152614a436102008501826148c9565b905060e0830151848203610100860152614a5d82826148c9565b915050610100830151614a74610120860182614812565b50610120830151614a89610140860182614812565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614abb82826148c9565b9150506101a0830151614ad26101c0860182614812565b506101c08301518015156101e0860152613a9a565b602081525f6147f460208301846149d6565b5f60208284031215614b09575f5ffd5b81356001600160401b03811115614b1e575f5ffd5b614b2a84828501614631565b949350505050565b5f60208284031215614b42575f5ffd5b81356001600160401b03811115614b57575f5ffd5b820161010081850312156147f4575f5ffd5b828152604060208201525f614b2a60408301846149d6565b5f60208284031215614b91575f5ffd5b81356001600160401b03811115614ba6575f5ffd5b614b2a8482850161469c565b5f5f60408385031215614bc3575f5ffd5b823591506020830135614bd581614597565b809150509250929050565b5f5f60408385031215614bf1575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101613842565b8215158152604081016147f46020830184614897565b5f5f83601f840112614c47575f5ffd5b5081356001600160401b03811115614c5d575f5ffd5b602083019150836020828501011115613cbe575f5ffd5b5f5f5f5f5f60608688031215614c88575f5ffd5b8535945060208601356001600160401b03811115614ca4575f5ffd5b614cb088828901614c37565b90955093505060408601356001600160401b03811115614cce575f5ffd5b614cda88828901614c37565b969995985093965092949392505050565b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d4560e0840182614812565b50610100830151614d5d61010084018261ffff169052565b50610120830151614d7561012084018261ffff169052565b50610140830151614d8d61014084018261ffff169052565b50610160830151614da561016084018261ffff169052565b50610180830151614dbd61018084018261ffff169052565b506101a0830151614dd76101a084018263ffffffff169052565b506101c0830151614df16101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614e0e575f5ffd5b8735965060208801356001600160401b03811115614e2a575f5ffd5b614e368a828b01614c37565b90975095505060408801356001600160401b03811115614e54575f5ffd5b614e608a828b01614c37565b90955093505060608801356001600160401b03811115614e7e575f5ffd5b614e8a8a828b01614c37565b989b979a50959850939692959293505050565b5f5f60408385031215614eae575f5ffd5b82359150602083013560ff81168114614bd5575f5ffd5b600781106148a7576148a7614883565b602081016138428284614ec5565b5f6101e0828403128015614ef5575f5ffd5b509092915050565b5f5f60608385031215614f0e575f5ffd5b614f1783614833565b915083606084011115614f28575f5ffd5b50926020919091019150565b600181811c90821680614f4857607f821691505b60208210810361126357634e487b7160e01b5f52602260045260245ffd5b5f60208284031215614f76575f5ffd5b6147f482614833565b634e487b7160e01b5f52603260045260245ffd5b6020810161384282846148b9565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561384257613842614fa1565b8082018082111561384257613842614fa1565b5f60018201614fec57614fec614fa1565b5060010190565b5f5f8335601e19843603018112615008575f5ffd5b8301803591506001600160401b03821115615021575f5ffd5b602001915036819003821315613cbe575f5ffd5b8015158114610d3f575f5ffd5b5f60208284031215615052575f5ffd5b81356147f481615035565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6150a460a08301888a61505d565b82810360608401526150b781878961505d565b905082810360808401526150cc81858761505d565b9b9a5050505050505050505050565b5f602082840312156150eb575f5ffd5b5051919050565b601f821115613b3857805f5260205f20601f840160051c810160208510156151175750805b601f840160051c820191505b81811015615136575f8155600101615123565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b0381111561516a5761516a6145cb565b61517e816151788454614f34565b846150f2565b6020601f8211600181146151ab575f83156151995750848201515b6151a3848261513d565b855550615136565b5f84815260208120601f198516915b828110156151da57878501518255602094850194600190920191016151ba565b50848210156151f757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561524057815163ffffffff1683526020928301929091019060010161521b565b505050949350505050565b5f6020828403121561525b575f5ffd5b81516147f481615035565b604081016152748285614ec5565b6147f46020830184614ec5565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156152ee57603f198786030184526152d98583516148c9565b945060209384019391909101906001016152bd565b50929695505050505050565b8381526060810161530e6020830185614ec5565b614b2a6040830184614ec5565b5f8151808452602084019350602083015f5b828110156153545781516001600160a01b031686526020958601959091019060010161532d565b5093949350505050565b848152836020820152608060408201525f61537c608083018561531b565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f61440460608301848661505d565b602081525f614b2a60208301848661505d565b6001600160401b038311156153ed576153ed6145cb565b615401836153fb8354614f34565b836150f2565b5f601f84116001811461542d575f851561541b5750838201355b615425868261513d565b845550615136565b5f83815260208120601f198716915b8281101561545c578685013582556020948501946001909201910161543c565b5086821015615478575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6154a360608301868861505d565b82810360408401526154b681858761505d565b98975050505050505050565b604081525f6154d560408301868861505d565b82810360208401526154e881858761505d565b979650505050505050565b61ffff81168114610d3f575f5ffd5b80356145b6816154f3565b5f6020828403121561551d575f5ffd5b81356147f4816154f3565b63ffffffff81168114610d3f575f5ffd5b80356145b681615528565b5f60208284031215615554575f5ffd5b81356147f481615528565b5f813561384281614597565b5f8135613842816154f3565b5f813561384281615528565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016155f36155d660e0850161555f565b82546001600160a01b0319166001600160a01b0391909116178255565b615623615603610100850161556b565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b615653615633610120850161556b565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b615683615663610140850161556b565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6156b3615693610160850161556b565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6156e36156c3610180850161556b565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161570f6156f86101a08501615577565b825463ffffffff191663ffffffff91909116178255565b613b3861571f6101c08501615577565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161579260e084016145ab565b61579f60e0840182614812565b506157ad6101008401615502565b61ffff166101008301526157c46101208401615502565b61ffff166101208301526157db6101408401615502565b61ffff166101408301526157f26101608401615502565b61ffff166101608301526158096101808401615502565b61ffff166101808301526158206101a08401615539565b63ffffffff166101a08301526158396101c08401615539565b63ffffffff81166101c0840152614df1565b808202811582820484141761384257613842614fa1565b5f8261587c57634e487b7160e01b5f52601260045260245ffd5b500490565b6040810181835f5b60028110156158b857813561589d81615528565b63ffffffff1683526020928301929190910190600101615889565b50505092915050565b604081016158cf8285614ec5565b6147f46020830184614897565b5f82601f8301126158eb575f5ffd5b81516158f96146b98261460f565b8082825260208201915060208360051b86010192508583111561591a575f5ffd5b602085015b8381101561471f57805183526020928301920161591f565b5f5f60408385031215615948575f5ffd5b82516001600160401b0381111561595d575f5ffd5b8301601f8101851361596d575f5ffd5b805161597b6146b98261460f565b8082825260208201915060208360051b85010192508783111561599c575f5ffd5b6020840193505b828410156159c75783516159b681614597565b8252602093840193909101906159a3565b8095505050505060208301516001600160401b038111156159e6575f5ffd5b6159f2858286016158dc565b9150509250929050565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f615a2d606083018561531b565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b82811015615354578151865260209586019590910190600101615a57565b6001600160a01b03841681526060602082018190525f90615a989083018561531b565b82810360408401526144048185615a45565b604081525f615abc604083018561531b565b8281036020840152615ace8185615a45565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615a05806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c80639117173c11610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610607578063ac3d2f4214610759578063b27392d514610781578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b80639117173c146105625780639231238614610575578063929a8faf1461058857806399c6679d146105a95780639c8570c8146105d15780639e57b934146105f4575f5ffd5b80635d1684181161022f57806381476ec2116101e957806381476ec2146104e7578063830d7181146104fa578063858142431461050d5780638da5cb5b146105205780638dcdd86b146105285780638e5ce3ad1461053a57806390173a411461054d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e03660046145d4565b61092e565b005b61030f6102f53660046145f6565b5f908152600960205260409020546001600160a01b031690565b60405161031c919061461a565b60405180910390f35b61030f6103333660046145f6565b60096020525f90815260409020546001600160a01b031681565b61036061035b366004614641565b6109da565b60405163ffffffff909116815260200161031c565b6102e56103833660046145d4565b610a16565b6102e5610396366004614679565b610abb565b6103bd6103a93660046145f6565b5f908152600f602052604090205460ff1690565b60405161031c91906146bb565b6103dd6103d83660046145f6565b610acf565b60405161031c9e9d9c9b9a99989796959493929190614707565b61040a6104053660046145f6565b610c7a565b60405161031c91906148e1565b6104366104253660046145f6565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e56104523660046148fe565b610ef7565b6102e56104653660046145f6565b611134565b6102e56104783660046145d4565b6111c3565b61049061048b366004614994565b611256565b60405161031c91906149ad565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ed565b6102e56104cf3660046149bf565b611300565b6102e56104e23660046145f6565b611389565b6102e56104f53660046149ed565b611488565b6102e5610508366004614a4a565b61157c565b60015461030f906001600160a01b031681565b61030f611688565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b6105556116b6565b60405161031c9190614a98565b6102e56105703660046145f6565b6116fc565b6105556105833660046145f6565b61186a565b61059b6105963660046145f6565b6118c3565b60405161031c929190614ab9565b61030f6105b73660046145f6565b5f908152601060205260409020546001600160a01b031690565b6105e46105df366004614acf565b6118ea565b604051901515815260200161031c565b610436610602366004614b46565b611b82565b61074c604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614b7d565b61030f6107673660046145f6565b5f908152600a60205260409020546001600160a01b031690565b6105e461078f366004614c8a565b612157565b6102e56107a2366004614d2f565b612387565b6102e56107b53660046145d4565b612443565b6102e56107c83660046149ed565b6124ea565b6105e46107db3660046145d4565b60076020525f908152604090205460ff1681565b61043660065481565b6102e56108063660046149bf565b6125a7565b6102e56108193660046145f6565b612661565b61084061082c3660046145f6565b5f908152600d602052604090205460ff1690565b60405161031c9190614d69565b6102e561085b366004614d77565b61269e565b6102e561086e3660046145d4565b61292b565b6102e5610881366004614d91565b6129c5565b60025461030f906001600160a01b031681565b6102e56108a73660046145d4565b612c72565b6108bf6108ba366004614b46565b612cac565b60405161031c929190614dc8565b6103bd6108db3660046145f6565b61358d565b6102e56108ee3660046145d4565b613727565b61030f6109013660046145f6565b600a6020525f90815260409020546001600160a01b031681565b6102e56109293660046145d4565b6137bf565b61093661384e565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e61384e565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b8152600401610988919061461a565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab090839061461a565b60405180910390a150565b610ac361384e565b610acc81613880565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614de8565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614de8565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c82614442565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614693565b6003811115610cd057610cd0614693565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614de8565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614de8565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f0061393d565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613967565b610fa987612661565b610fb28b613727565b610fbb8a61292b565b610fc48961092e565b610fcd88610a16565b610fd686613880565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff191690556110bf611688565b6001600160a01b03168c6001600160a01b0316146110e0576110e08c612c72565b831561112657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113c61384e565b5f8181526009602052604090205481906001600160a01b0316611175576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cb61384e565b6001600160a01b0381165f90815260076020526040902054819060ff16611206576040516321ac7c5f60e01b8152600401610988919061461a565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab090839061461a565b600b6020525f90815260409020805461126e90614de8565b80601f016020809104026020016040519081016040528092919081815260200182805461129a90614de8565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b505050505081565b6112f561384e565b6112fe5f613978565b565b61130861384e565b6001600160a01b0381161580159061133957505f828152600a60205260409020546001600160a01b03828116911614155b829061135b576040516381c4951960e01b815260040161098891815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b031633146113b35760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff1660018160068111156113d8576113d8614693565b146113fd57816001826040516337e1404160e01b815260040161098893929190614e1a565b5f828152600d60205260409020805460ff191660021790556015546114229042614e4f565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206159d95f395f51905f526001600260405161147c929190614e62565b60405180910390a25050565b5f546001600160a01b031633146114b25760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff1660028160068111156114e2576114e2614693565b1461150757836002826040516337e1404160e01b815260040161098893929190614e1a565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206159d95f395f51905f526002600360405161156e929190614e62565b60405180910390a250505050565b61158461384e565b806115c05760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b6020526040902080546115dc90614de8565b15905061162b5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b60205260409020611647828483614ef0565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da219583838360405161167b93929190614fcc565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6116d760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff16600681600681111561172157611721614693565b14829061174457604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c60205260409020548281611775576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c6020526040812081905561178f846139e8565b5f858152601160205260409020546002549192506001600160a01b03908116916117bc9183911685613ad5565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b697906117f2908890879087908790600401615034565b5f604051808303815f87803b158015611809575f5ffd5b505af115801561181b573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a0731784845160405161185b929190918252602082015260400190565b60405180910390a25050505050565b61188b60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166118e08482613b32565b9250925050915091565b5f5f6118f587610c7a565b5f888152600d602052604090205490915060ff16600381600681111561191d5761191d614693565b1488600383909192611945576040516337e1404160e01b815260040161098893929190614e1a565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156119a9576040516308f3034360e31b815260048101929092526024820152604401610988565b50506060830151602001518990428111156119e05760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611a0b57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611a1d92919061507f565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611a5f9042614e4f565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611aac908d9085908c908c9060040161508e565b6020604051808303815f875af1158015611ac8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aec91906150ba565b9450888886611b1057604051632f9f8ab960e01b81526004016109889291906150d5565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611b449291906150d5565b60405180910390a2895f5160206159d95f395f51905f5260036004604051611b6d929190614e62565b60405180910390a25050505095945050505050565b5f80600b81611b9760a0860160808701614994565b60ff1660ff1681526020019081526020015f208054611bb590614de8565b905011611bd45760405162461bcd60e51b8152600401610988906150e8565b5f601281611be5602086018661511f565b6003811115611bf657611bf6614693565b6003811115611c0757611c07614693565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611c2e579050505050505090505f81600160028110611c8557611c8561506b565b602002015163ffffffff1611835f016020810190611ca3919061511f565b90611cc25760405163286c068d60e11b81526004016109889190615138565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115611ded576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190611dcc919061511f565b90611deb5760405163010b971d60e31b81526004016109889190615138565b505b6101c081015163ffffffff1615611e3c576101c081015184519063ffffffff9081169082161015611e3a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b60408601356020870135811015611e695760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f9161271091611e879161ffff1690615146565b611e91919061515d565b61271061ffff1683610160015161ffff16601560010154611eb29190615146565b611ebc919061515d565b61271061ffff1684610140015161ffff1660155f0154611edc9190615146565b611ee6919061515d565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015611f32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f56919061517c565b611f609190614e4f565b611f6a9190615193565b611f749190614e4f565b611f7e9190614e4f565b611f889190614e4f565b90505f611f96600186615193565b611fa1906002615146565b611fac906002615146565b611fb7906006614e4f565b90505f85845f0151611fc99190615146565b905081868560200151611fdc9190615146565b611fe69190615146565b611ff09082614e4f565b90506001861115612038576002612008600188615193565b6120129088615146565b85604001516120219190615146565b61202b919061515d565b6120359082614e4f565b90505b81868560c001516120499190615146565b6120539190615146565b61205d9082614e4f565b9050828685606001516120709190615146565b61207a9190615146565b6120849082614e4f565b90508484608001516120969190615146565b6120a09082614e4f565b905060018511156120e85760026120b8600187615193565b6120c29087615146565b85604001516120d19190615146565b6120db919061515d565b6120e59082614e4f565b90505b60a08401516120f79082614e4f565b610100850151909150612710906121129061ffff1682614e4f565b61211c9083615146565b612126919061515d565b9750878061214a57604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f5f61216289610c7a565b5f8a8152600d602052604090205490915060ff16600481600681111561218a5761218a614693565b148a6004839091926121b2576040516337e1404160e01b815260040161098893929190614e1a565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b9042811015612215576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f8b8152600860205260409020600c016122328a8c83614ef0565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161227692919061507f565b6040519081900381206001600160e01b031960e084901b1682526122a4918c908c908c908c906004016151a6565b602060405180830381865afa1580156122bf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e391906150ba565b935089898561230757604051632f9f8ab960e01b81526004016109889291906150d5565b50506123128b613cba565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161234894939291906151de565b60405180910390a28a5f5160206159d95f395f51905f5260046005604051612371929190614e62565b60405180910390a2505050979650505050505050565b5f546001600160a01b03163314806123a957506003546001600160a01b031633145b6123c657604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156123dc5750600d60ff821611155b6124215760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b61243f828260ff16600d81111561243a5761243a614693565b614126565b5050565b61244b61384e565b6001600160a01b0381166124a15760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612515576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561255f575f5ffd5b505af1158015612571573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee5428260405161147c91815260200190565b6125af61384e565b6001600160a01b038116158015906125e057505f828152600960205260409020546001600160a01b03828116911614155b8290612602576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b61266961384e565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b6126a661384e565b6127106126bb61012083016101008401615229565b61ffff1611156126d361012083016101008401615229565b906126f8576040516301027fc160e21b815261ffff9091166004820152602401610988565b5061271061270e61014083016101208401615229565b61ffff16111561272661014083016101208401615229565b9061274b576040516301027fc160e21b815261ffff9091166004820152602401610988565b5061271061276161016083016101408401615229565b61ffff16111561277961016083016101408401615229565b9061279e57604051633239953960e01b815261ffff9091166004820152602401610988565b506127106127b461018083016101608401615229565b61ffff1611156127cc61018083016101608401615229565b906127f157604051633239953960e01b815261ffff9091166004820152602401610988565b506127106128076101a083016101808401615229565b61ffff16111561281f6101a083016101808401615229565b9061284457604051633239953960e01b815261ffff9091166004820152602401610988565b5061285761014082016101208301615229565b61ffff16158061288057505f612874610100830160e084016145d4565b6001600160a01b031614155b61289d5760405163015f92ff60e51b815260040160405180910390fd5b6128af6101e082016101c08301615260565b63ffffffff166128c76101c083016101a08401615260565b63ffffffff1610156128ec576040516392f55c6560e01b815260040160405180910390fd5b8060186128f9828261529f565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061545d565b61293361384e565b6001600160a01b0381161580159061295957506001546001600160a01b03828116911614155b8190612979576040516320252f0b60e01b8152600401610988919061461a565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab090839061461a565b6129cd61384e565b6129da6020820182615260565b63ffffffff166129f06040830160208401615260565b63ffffffff1610158015612a1557505f612a0d6020830183615260565b63ffffffff16115b612a3257604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612b6b576101a081015163ffffffff16612b1b6040840160208501615260565b63ffffffff161015612b336040840160208501615260565b826101a001519091612b6857604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612be2576101c081015163ffffffff16612b956020840184615260565b63ffffffff161015612baa6020840184615260565b826101c001519091612bdf5760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612bf857612bf8614693565b6003811115612c0957612c09614693565b815260208101919091526040015f20612c239160026144bf565b50826003811115612c3657612c36614693565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612c659190615567565b60405180910390a2505050565b612c7a61384e565b6001600160a01b038116612ca3575f604051631e4fbdf760e01b8152600401610988919061461a565b610acc81613978565b5f612cb5614442565b5f601281612cc6602087018761511f565b6003811115612cd757612cd7614693565b6003811115612ce857612ce8614693565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612d0f579050505050505090505f81600160028110612d6657612d6661506b565b602002015163ffffffff1611845f016020810190612d84919061511f565b90612da35760405163286c068d60e11b81526004016109889190615138565b50602084013542811015612dcd57604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612dfb5760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612e13426040890135615193565b612e1d9190614e4f565b612e279190614e4f565b905060055481108190612e50576040516313b783af60e21b815260040161098891815260200190565b5060075f612e6460808801606089016145d4565b6001600160a01b0316815260208101919091526040015f205460ff16612e9060808701606088016145d4565b90612eaf5760405163295a6a6f60e11b8152600401610988919061461a565b505f612eba86611b82565b60068054965090915085905f612ecf836155a7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff191660011790556010909452829020805433941693909317909255601654919250612faa9190890135614e4f565b5f878152600e6020908152604090912060010191909155818652612fd09088018861511f565b85602001906003811115612fe657612fe6614693565b90816003811115612ff957612ff9614693565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261304190608089019089016145d4565b6001600160a01b031660a08087019190915261306290880160808901614994565b60ff1660c08087019190915261307a908801886155bf565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526130c7906101008901908901615601565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454613117916001600160a01b03909116903085614281565b5f600b8161312b60a08b0160808c01614994565b60ff1660ff1681526020019081526020015f20805461314990614de8565b80601f016020809104026020016040519081016040528092919081815260200182805461317590614de8565b80156131c05780601f10613197576101008083540402835291602001916131c0565b820191905f5260205f20905b8154815290600101906020018083116131a357829003601f168201915b505050505090505f8151116131e75760405162461bcd60e51b8152600401610988906150e8565b5f6131f860808a0160608b016145d4565b6001600160a01b031663fefd9a8b89858561321660a08f018f6155bf565b8f8060c0019061322691906155bf565b6040518863ffffffff1660e01b8152600401613248979695949392919061561c565b6020604051808303815f875af1158015613264573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613288919061517c565b5f818152600960205260409020549091506001600160a01b031681816132c4576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b031682816132fe576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561335c5761335c614693565b021790555060408201518160020155606082015181600301906002613382929190614560565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906133db9082615670565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906134439082615670565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b906134a9908d9089908d90600401615725565b6020604051808303815f875af11580156134c5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134e991906150ba565b61350657604051630d8dbe2560e01b815260040160405180910390fd5b61351660808c0160608d016145d4565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b604051613550929190614dc8565b60405180910390a2895f5160206159d95f395f51905f525f6001604051613578929190614e62565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff16818160068111156135b1576135b1614693565b036135d657826001826040516337e1404160e01b815260040161098893929190614e1a565b60058160068111156135ea576135ea614693565b0361360b5760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561361f5761361f614693565b0361364057604051633de16e3560e11b815260048101849052602401610988565b5f61364b8483613b32565b935090508061367057604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156136b9576136b9614693565b0217905550835f5160206159d95f395f51905f528360066040516136de929190614e62565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161371892919061576a565b60405180910390a25050919050565b61372f61384e565b6001600160a01b0381161580159061375457505f546001600160a01b03828116911614155b8190613774576040516375ac4eb760e11b8152600401610988919061461a565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab090839061461a565b6001600160a01b0381165f90815260076020526040902054819060ff16156137fb5760405163b29d459560e01b8152600401610988919061461a565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab090839061461a565b33613857611688565b6001600160a01b0316146112fe573360405163118cdaa760e01b8152600401610988919061461a565b803561389f5760405163055f269d60e01b815260040160405180910390fd5b5f8160200135116138c35760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138e75760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b61396f6142c0565b610acc816142e5565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a1057613a10614693565b1480613a2d5750600281600d811115613a2b57613a2b614693565b145b15613a65575f5b604051908082528060200260200182016040528015613a5d578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613acb57506040513d5f823e601f3d908101601f19168201604052613ac89190810190615841565b60015b613a5d575f613a34565b613b2d83846001600160a01b031663a9059cbb8585604051602401613afb929190615906565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142ed565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bac573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bd0919061517c565b90506001856006811115613be657613be6614693565b148015613bf257508042115b15613c0557600180935093505050613cb3565b6002856006811115613c1957613c19614693565b148015613c265750815142115b15613c3a5760016003935093505050613cb3565b6003856006811115613c4e57613c4e614693565b148015613c5e5750816020015142115b15613c725760016006935093505050613cb3565b6004856006811115613c8657613c86614693565b148015613c965750816040015142115b15613caa576001600a935093505050613cb3565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613cff573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d269190810190615841565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dc5576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d919088908890869060040161591f565b5f604051808303815f87803b158015613da8575f5ffd5b505af1158015613dba573d5f5f3e3d5ffd5b505050505050505050565b825f03613e66575f858152601060205260409020546001600160a01b03168015613dfd57613dfd6001600160a01b0383168285613ad5565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e319089908990879060040161591f565b5f604051808303815f87803b158015613e48575f5ffd5b505af1158015613e5a573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613ea657506001600160a01b03811615155b15613ee257612710613ebc61ffff841687615146565b613ec6919061515d565b92508215613ee257613ee26001600160a01b0385168285613ad5565b5f613eed8487615193565b90505f876001600160401b03811115613f0857613f08614e7d565b604051908082528060200260200182016040528015613f31578160200160208202803683370190505b5090505f613f3f898461515d565b90505f805b8a811015613f7e5782848281518110613f5f57613f5f61506b565b6020908102919091010152613f748383614e4f565b9150600101613f44565b505f613f8a8286615193565b90508015613fc7578084613f9f60018e615193565b81518110613faf57613faf61506b565b60200260200101818151613fc39190614e4f565b9052505b600154613fe1906001600160a01b038b8116911687614350565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b81526004016140259392919061597f565b5f604051808303815f87803b15801561403c575f5ffd5b505af115801561404e573d5f5f3e3d5ffd5b505060015461406c92506001600160a01b038c81169250165f614350565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8660405161409e9291906159b4565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140ea9392919061591f565b5f604051808303815f87803b158015614101575f5ffd5b505af1158015614113573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561414a5761414a614693565b0361416f57826001826040516337e1404160e01b815260040161098893929190614e1a565b600581600681111561418357614183614693565b036141a45760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156141b8576141b8614693565b036141d957604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561422257614222614693565b0217905550825f5160206159d95f395f51905f52826006604051614247929190614e62565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612c6592919061576a565b6040516001600160a01b0384811660248301528381166044830152606482018390526142ba9186918216906323b872dd90608401613afb565b50505050565b6142c86143e0565b6112fe57604051631afcd79f60e31b815260040160405180910390fd5b612c7a6142c0565b5f5f60205f8451602086015f885af18061430c576040513d5f823e3d81fd5b50505f513d91508115614323578060011415614330565b6001600160a01b0384163b155b156142ba5783604051635274afe760e01b8152600401610988919061461a565b5f836001600160a01b031663095ea7b38484604051602401614373929190615906565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506143ac84826143f9565b6142ba576143d684856001600160a01b031663095ea7b3865f604051602401613afb929190615906565b6142ba84826142ed565b5f6143e961393d565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156144385750811561442a5780600114614438565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161446a61458e565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b600183019183908215614550579160200282015f5b8382111561451e57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144d4565b801561454e5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261451e565b505b5061455c9291506145ac565b5090565b8260028101928215614550579160200282015b82811115614550578251825591602001919060010190614573565b60405180604001604052806002906020820280368337509192915050565b5b8082111561455c575f81556001016145ad565b6001600160a01b0381168114610acc575f5ffd5b5f602082840312156145e4575f5ffd5b81356145ef816145c0565b9392505050565b5f60208284031215614606575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b80356004811061463c575f5ffd5b919050565b5f5f60408385031215614652575f5ffd5b61465b8361462e565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f60608284031215614689575f5ffd5b6145ef8383614669565b634e487b7160e01b5f52602160045260245ffd5b600e81106146b7576146b7614693565b9052565b6020810161396182846146a7565b600481106146b7576146b7614693565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614717602082018f6146c9565b8c60408201528b6060820152614730608082018c61460d565b60ff8a1660a08201526101c060c08201525f6147506101c083018b6146d9565b61475d60e084018b61460d565b61476b61010084018a61460d565b876101208401528661014084015282810361016084015261478c81876146d9565b91505061479d61018083018561460d565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156142ba5781518452602093840193909101906001016147bc565b805182525f60208201516147f260208501826146c9565b5060408201516040840152606082015161480f60608501826147b9565b50608082015160a084015260a082015161482c60c085018261460d565b5060c082015160ff811660e08501525060e08201516102006101008501526148586102008501826146d9565b905061010083015161486e61012086018261460d565b5061012083015161488361014086018261460d565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148b582826146d9565b9150506101a08301516148cc6101c086018261460d565b506101c08301518015156101e0860152613a5d565b602081525f6145ef60208301846147db565b803561463c816145c0565b5f5f5f5f5f5f5f610120888a031215614915575f5ffd5b8735614920816145c0565b96506020880135614930816145c0565b95506040880135614940816145c0565b94506060880135614950816145c0565b93506080880135614960816145c0565b925060a088013591506149768960c08a01614669565b905092959891949750929550565b803560ff8116811461463c575f5ffd5b5f602082840312156149a4575f5ffd5b6145ef82614984565b602081525f6145ef60208301846146d9565b5f5f604083850312156149d0575f5ffd5b8235915060208301356149e2816145c0565b809150509250929050565b5f5f604083850312156149fe575f5ffd5b50508035926020909101359150565b5f5f83601f840112614a1d575f5ffd5b5081356001600160401b03811115614a33575f5ffd5b602083019150836020828501011115613cb3575f5ffd5b5f5f5f60408486031215614a5c575f5ffd5b614a6584614984565b925060208401356001600160401b03811115614a7f575f5ffd5b614a8b86828701614a0d565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613961565b8215158152604081016145ef60208301846146a7565b5f5f5f5f5f60608688031215614ae3575f5ffd5b8535945060208601356001600160401b03811115614aff575f5ffd5b614b0b88828901614a0d565b90955093505060408601356001600160401b03811115614b29575f5ffd5b614b3588828901614a0d565b969995985093965092949392505050565b5f60208284031215614b56575f5ffd5b81356001600160401b03811115614b6b575f5ffd5b820161010081850312156145ef575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614bd760e084018261460d565b50610100830151614bef61010084018261ffff169052565b50610120830151614c0761012084018261ffff169052565b50610140830151614c1f61014084018261ffff169052565b50610160830151614c3761016084018261ffff169052565b50610180830151614c4f61018084018261ffff169052565b506101a0830151614c696101a084018263ffffffff169052565b506101c0830151614c836101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614ca0575f5ffd5b8735965060208801356001600160401b03811115614cbc575f5ffd5b614cc88a828b01614a0d565b90975095505060408801356001600160401b03811115614ce6575f5ffd5b614cf28a828b01614a0d565b90955093505060608801356001600160401b03811115614d10575f5ffd5b614d1c8a828b01614a0d565b989b979a50959850939692959293505050565b5f5f60408385031215614d40575f5ffd5b82359150614d5060208401614984565b90509250929050565b600781106146b7576146b7614693565b602081016139618284614d59565b5f6101e0828403128015614d89575f5ffd5b509092915050565b5f5f60608385031215614da2575f5ffd5b614dab8361462e565b915083606084011115614dbc575f5ffd5b50926020919091019150565b828152604060208201525f614de060408301846147db565b949350505050565b600181811c90821680614dfc57607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614e2e6020830185614d59565b614de06040830184614d59565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561396157613961614e3b565b60408101614e708285614d59565b6145ef6020830184614d59565b634e487b7160e01b5f52604160045260245ffd5b601f821115613b2d57805f5260205f20601f840160051c81016020851015614eb65750805b601f840160051c820191505b81811015614ed5575f8155600101614ec2565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b03831115614f0757614f07614e7d565b614f1b83614f158354614de8565b83614e91565b5f601f841160018114614f47575f8515614f355750838201355b614f3f8682614edc565b845550614ed5565b5f83815260208120601f198716915b82811015614f765786850135825560209485019460019092019101614f56565b5086821015614f92575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60ff84168152604060208201525f614fe8604083018486614fa4565b95945050505050565b5f8151808452602084019350602083015f5b8281101561502a5781516001600160a01b0316865260209586019590910190600101615003565b5093949350505050565b848152836020820152608060408201525f6150526080830185614ff1565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b818382375f9101908152919050565b848152836020820152606060408201525f614438606083018486614fa4565b8015158114610acc575f5ffd5b5f602082840312156150ca575f5ffd5b81516145ef816150ad565b602081525f614de0602083018486614fa4565b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f6020828403121561512f575f5ffd5b6145ef8261462e565b6020810161396182846146c9565b808202811582820484141761396157613961614e3b565b5f8261517757634e487b7160e01b5f52601260045260245ffd5b500490565b5f6020828403121561518c575f5ffd5b5051919050565b8181038181111561396157613961614e3b565b858152606060208201525f6151bf606083018688614fa4565b82810360408401526151d2818587614fa4565b98975050505050505050565b604081525f6151f1604083018688614fa4565b8281036020840152615204818587614fa4565b979650505050505050565b61ffff81168114610acc575f5ffd5b803561463c8161520f565b5f60208284031215615239575f5ffd5b81356145ef8161520f565b63ffffffff81168114610acc575f5ffd5b803561463c81615244565b5f60208284031215615270575f5ffd5b81356145ef81615244565b5f8135613961816145c0565b5f81356139618161520f565b5f813561396181615244565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161530f6152f260e0850161527b565b82546001600160a01b0319166001600160a01b0391909116178255565b61533f61531f6101008501615287565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61536f61534f6101208501615287565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61539f61537f6101408501615287565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6153cf6153af6101608501615287565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6153ff6153df6101808501615287565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161542b6154146101a08501615293565b825463ffffffff191663ffffffff91909116178255565b613b2d61543b6101c08501615293565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016154ae60e084016148f3565b6154bb60e084018261460d565b506154c9610100840161521e565b61ffff166101008301526154e0610120840161521e565b61ffff166101208301526154f7610140840161521e565b61ffff1661014083015261550e610160840161521e565b61ffff16610160830152615525610180840161521e565b61ffff1661018083015261553c6101a08401615255565b63ffffffff166101a08301526155556101c08401615255565b63ffffffff81166101c0840152614c83565b6040810181835f5b600281101561559e57813561558381615244565b63ffffffff168352602092830192919091019060010161556f565b50505092915050565b5f600182016155b8576155b8614e3b565b5060010190565b5f5f8335601e198436030181126155d4575f5ffd5b8301803591506001600160401b038211156155ed575f5ffd5b602001915036819003821315613cb3575f5ffd5b5f60208284031215615611575f5ffd5b81356145ef816150ad565b87815286602082015260a060408201525f61563a60a08301886146d9565b828103606084015261564d818789614fa4565b90508281036080840152615662818587614fa4565b9a9950505050505050505050565b81516001600160401b0381111561568957615689614e7d565b61569d816156978454614de8565b84614e91565b6020601f8211600181146156ca575f83156156b85750848201515b6156c28482614edc565b855550614ed5565b5f84815260208120601f198516915b828110156156f957878501518255602094850194600190920191016156d9565b508482101561571657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561575f57815163ffffffff1683526020928301929091019060010161573a565b505050949350505050565b604081016157788285614d59565b6145ef60208301846146a7565b604051601f8201601f191681016001600160401b03811182821017156157ad576157ad614e7d565b604052919050565b5f6001600160401b038211156157cd576157cd614e7d565b5060051b60200190565b5f82601f8301126157e6575f5ffd5b81516157f96157f4826157b5565b615785565b8082825260208201915060208360051b86010192508583111561581a575f5ffd5b602085015b8381101561583757805183526020928301920161581f565b5095945050505050565b5f5f60408385031215615852575f5ffd5b82516001600160401b03811115615867575f5ffd5b8301601f81018513615877575f5ffd5b80516158856157f4826157b5565b8082825260208201915060208360051b8501019250878311156158a6575f5ffd5b6020840193505b828410156158d15783516158c0816145c0565b8252602093840193909101906158ad565b8095505050505060208301516001600160401b038111156158f0575f5ffd5b6158fc858286016157d7565b9150509250929050565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6159376060830185614ff1565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561502a578151865260209586019590910190600101615961565b6001600160a01b03841681526060602082018190525f906159a290830185614ff1565b8281036040840152614438818561594f565b604081525f6159c66040830185614ff1565b8281036020840152614fe8818561594f56fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c80639117173c11610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b8063a87f4ab91161013c578063a87f4ab914610607578063ac3d2f4214610759578063b27392d514610781578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b80639117173c146105625780639231238614610575578063929a8faf1461058857806399c6679d146105a95780639c8570c8146105d15780639e57b934146105f4575f5ffd5b80635d1684181161022f57806381476ec2116101e957806381476ec2146104e7578063830d7181146104fa578063858142431461050d5780638da5cb5b146105205780638dcdd86b146105285780638e5ce3ad1461053a57806390173a411461054d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e03660046145d4565b61092e565b005b61030f6102f53660046145f6565b5f908152600960205260409020546001600160a01b031690565b60405161031c919061461a565b60405180910390f35b61030f6103333660046145f6565b60096020525f90815260409020546001600160a01b031681565b61036061035b366004614641565b6109da565b60405163ffffffff909116815260200161031c565b6102e56103833660046145d4565b610a16565b6102e5610396366004614679565b610abb565b6103bd6103a93660046145f6565b5f908152600f602052604090205460ff1690565b60405161031c91906146bb565b6103dd6103d83660046145f6565b610acf565b60405161031c9e9d9c9b9a99989796959493929190614707565b61040a6104053660046145f6565b610c7a565b60405161031c91906148e1565b6104366104253660046145f6565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e56104523660046148fe565b610ef7565b6102e56104653660046145f6565b611134565b6102e56104783660046145d4565b6111c3565b61049061048b366004614994565b611256565b60405161031c91906149ad565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ed565b6102e56104cf3660046149bf565b611300565b6102e56104e23660046145f6565b611389565b6102e56104f53660046149ed565b611488565b6102e5610508366004614a4a565b61157c565b60015461030f906001600160a01b031681565b61030f611688565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b6105556116b6565b60405161031c9190614a98565b6102e56105703660046145f6565b6116fc565b6105556105833660046145f6565b61186a565b61059b6105963660046145f6565b6118c3565b60405161031c929190614ab9565b61030f6105b73660046145f6565b5f908152601060205260409020546001600160a01b031690565b6105e46105df366004614acf565b6118ea565b604051901515815260200161031c565b610436610602366004614b46565b611b82565b61074c604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614b7d565b61030f6107673660046145f6565b5f908152600a60205260409020546001600160a01b031690565b6105e461078f366004614c8a565b612157565b6102e56107a2366004614d2f565b612387565b6102e56107b53660046145d4565b612443565b6102e56107c83660046149ed565b6124ea565b6105e46107db3660046145d4565b60076020525f908152604090205460ff1681565b61043660065481565b6102e56108063660046149bf565b6125a7565b6102e56108193660046145f6565b612661565b61084061082c3660046145f6565b5f908152600d602052604090205460ff1690565b60405161031c9190614d69565b6102e561085b366004614d77565b61269e565b6102e561086e3660046145d4565b61292b565b6102e5610881366004614d91565b6129c5565b60025461030f906001600160a01b031681565b6102e56108a73660046145d4565b612c72565b6108bf6108ba366004614b46565b612cac565b60405161031c929190614dc8565b6103bd6108db3660046145f6565b61358d565b6102e56108ee3660046145d4565b613727565b61030f6109013660046145f6565b600a6020525f90815260409020546001600160a01b031681565b6102e56109293660046145d4565b6137bf565b61093661384e565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e61384e565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b8152600401610988919061461a565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab090839061461a565b60405180910390a150565b610ac361384e565b610acc81613880565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614de8565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614de8565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c82614442565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614693565b6003811115610cd057610cd0614693565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614de8565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614de8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614de8565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f0061393d565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613967565b610fa987612661565b610fb28b613727565b610fbb8a61292b565b610fc48961092e565b610fcd88610a16565b610fd686613880565b604080516101e08101825261c3508082526161a86020808401829052611388948401859052601460608501819052620249f0608086018190526207a12060a087018190526107d060c088018190525f60e089018190526103e86101008a015261012089018190526109c46101408a018190526101608a018b90526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b031916690138827101388000007d60a31b179055805467ffffffffffffffff191690556110bf611688565b6001600160a01b03168c6001600160a01b0316146110e0576110e08c612c72565b831561112657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113c61384e565b5f8181526009602052604090205481906001600160a01b0316611175576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cb61384e565b6001600160a01b0381165f90815260076020526040902054819060ff16611206576040516321ac7c5f60e01b8152600401610988919061461a565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab090839061461a565b600b6020525f90815260409020805461126e90614de8565b80601f016020809104026020016040519081016040528092919081815260200182805461129a90614de8565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b505050505081565b6112f561384e565b6112fe5f613978565b565b61130861384e565b6001600160a01b0381161580159061133957505f828152600a60205260409020546001600160a01b03828116911614155b829061135b576040516381c4951960e01b815260040161098891815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b031633146113b35760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff1660018160068111156113d8576113d8614693565b146113fd57816001826040516337e1404160e01b815260040161098893929190614e1a565b5f828152600d60205260409020805460ff191660021790556015546114229042614e4f565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206159d95f395f51905f526001600260405161147c929190614e62565b60405180910390a25050565b5f546001600160a01b031633146114b25760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff1660028160068111156114e2576114e2614693565b1461150757836002826040516337e1404160e01b815260040161098893929190614e1a565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206159d95f395f51905f526002600360405161156e929190614e62565b60405180910390a250505050565b61158461384e565b806115c05760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b6020526040902080546115dc90614de8565b15905061162b5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b60205260409020611647828483614ef0565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da219583838360405161167b93929190614fcc565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6116d760405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff16600681600681111561172157611721614693565b14829061174457604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c60205260409020548281611775576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c6020526040812081905561178f846139e8565b5f858152601160205260409020546002549192506001600160a01b03908116916117bc9183911685613ad5565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b697906117f2908890879087908790600401615034565b5f604051808303815f87803b158015611809575f5ffd5b505af115801561181b573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a0731784845160405161185b929190918252602082015260400190565b60405180910390a25050505050565b61188b60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff166118e08482613b32565b9250925050915091565b5f5f6118f587610c7a565b5f888152600d602052604090205490915060ff16600381600681111561191d5761191d614693565b1488600383909192611945576040516337e1404160e01b815260040161098893929190614e1a565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156119a9576040516308f3034360e31b815260048101929092526024820152604401610988565b50506060830151602001518990428111156119e05760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611a0b57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611a1d92919061507f565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611a5f9042614e4f565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611aac908d9085908c908c9060040161508e565b6020604051808303815f875af1158015611ac8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aec91906150ba565b9450888886611b1057604051632f9f8ab960e01b81526004016109889291906150d5565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611b449291906150d5565b60405180910390a2895f5160206159d95f395f51905f5260036004604051611b6d929190614e62565b60405180910390a25050505095945050505050565b5f80600b81611b9760a0860160808701614994565b60ff1660ff1681526020019081526020015f208054611bb590614de8565b905011611bd45760405162461bcd60e51b8152600401610988906150e8565b5f601281611be5602086018661511f565b6003811115611bf657611bf6614693565b6003811115611c0757611c07614693565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611c2e579050505050505090505f81600160028110611c8557611c8561506b565b602002015163ffffffff1611835f016020810190611ca3919061511f565b90611cc25760405163286c068d60e11b81526004016109889190615138565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c086015292831693919092169115611ded576101a081015163ffffffff16846001602002015163ffffffff161015865f016020810190611dcc919061511f565b90611deb5760405163010b971d60e31b81526004016109889190615138565b505b6101c081015163ffffffff1615611e3c576101c081015184519063ffffffff9081169082161015611e3a57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b60408601356020870135811015611e695760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f9161271091611e879161ffff1690615146565b611e91919061515d565b61271061ffff1683610160015161ffff16601560010154611eb29190615146565b611ebc919061515d565b61271061ffff1684610140015161ffff1660155f0154611edc9190615146565b611ee6919061515d565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015611f32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f56919061517c565b611f609190614e4f565b611f6a9190615193565b611f749190614e4f565b611f7e9190614e4f565b611f889190614e4f565b90505f611f96600186615193565b611fa1906002615146565b611fac906002615146565b611fb7906006614e4f565b90505f85845f0151611fc99190615146565b905081868560200151611fdc9190615146565b611fe69190615146565b611ff09082614e4f565b90506001861115612038576002612008600188615193565b6120129088615146565b85604001516120219190615146565b61202b919061515d565b6120359082614e4f565b90505b81868560c001516120499190615146565b6120539190615146565b61205d9082614e4f565b9050828685606001516120709190615146565b61207a9190615146565b6120849082614e4f565b90508484608001516120969190615146565b6120a09082614e4f565b905060018511156120e85760026120b8600187615193565b6120c29087615146565b85604001516120d19190615146565b6120db919061515d565b6120e59082614e4f565b90505b60a08401516120f79082614e4f565b610100850151909150612710906121129061ffff1682614e4f565b61211c9083615146565b612126919061515d565b9750878061214a57604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f5f61216289610c7a565b5f8a8152600d602052604090205490915060ff16600481600681111561218a5761218a614693565b148a6004839091926121b2576040516337e1404160e01b815260040161098893929190614e1a565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b9042811015612215576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f8b8152600860205260409020600c016122328a8c83614ef0565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b60405161227692919061507f565b6040519081900381206001600160e01b031960e084901b1682526122a4918c908c908c908c906004016151a6565b602060405180830381865afa1580156122bf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e391906150ba565b935089898561230757604051632f9f8ab960e01b81526004016109889291906150d5565b50506123128b613cba565b8a7f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8b8b8b8b60405161234894939291906151de565b60405180910390a28a5f5160206159d95f395f51905f5260046005604051612371929190614e62565b60405180910390a2505050979650505050505050565b5f546001600160a01b03163314806123a957506003546001600160a01b031633145b6123c657604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156123dc5750600d60ff821611155b6124215760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b61243f828260ff16600d81111561243a5761243a614693565b614126565b5050565b61244b61384e565b6001600160a01b0381166124a15760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b03163314612515576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561255f575f5ffd5b505af1158015612571573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee5428260405161147c91815260200190565b6125af61384e565b6001600160a01b038116158015906125e057505f828152600960205260409020546001600160a01b03828116911614155b8290612602576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b61266961384e565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b6126a661384e565b6127106126bb61012083016101008401615229565b61ffff1611156126d361012083016101008401615229565b906126f8576040516301027fc160e21b815261ffff9091166004820152602401610988565b5061271061270e61014083016101208401615229565b61ffff16111561272661014083016101208401615229565b9061274b576040516301027fc160e21b815261ffff9091166004820152602401610988565b5061271061276161016083016101408401615229565b61ffff16111561277961016083016101408401615229565b9061279e57604051633239953960e01b815261ffff9091166004820152602401610988565b506127106127b461018083016101608401615229565b61ffff1611156127cc61018083016101608401615229565b906127f157604051633239953960e01b815261ffff9091166004820152602401610988565b506127106128076101a083016101808401615229565b61ffff16111561281f6101a083016101808401615229565b9061284457604051633239953960e01b815261ffff9091166004820152602401610988565b5061285761014082016101208301615229565b61ffff16158061288057505f612874610100830160e084016145d4565b6001600160a01b031614155b61289d5760405163015f92ff60e51b815260040160405180910390fd5b6128af6101e082016101c08301615260565b63ffffffff166128c76101c083016101a08401615260565b63ffffffff1610156128ec576040516392f55c6560e01b815260040160405180910390fd5b8060186128f9828261529f565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061545d565b61293361384e565b6001600160a01b0381161580159061295957506001546001600160a01b03828116911614155b8190612979576040516320252f0b60e01b8152600401610988919061461a565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab090839061461a565b6129cd61384e565b6129da6020820182615260565b63ffffffff166129f06040830160208401615260565b63ffffffff1610158015612a1557505f612a0d6020830183615260565b63ffffffff16115b612a3257604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612b6b576101a081015163ffffffff16612b1b6040840160208501615260565b63ffffffff161015612b336040840160208501615260565b826101a001519091612b6857604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612be2576101c081015163ffffffff16612b956020840184615260565b63ffffffff161015612baa6020840184615260565b826101c001519091612bdf5760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612bf857612bf8614693565b6003811115612c0957612c09614693565b815260208101919091526040015f20612c239160026144bf565b50826003811115612c3657612c36614693565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612c659190615567565b60405180910390a2505050565b612c7a61384e565b6001600160a01b038116612ca3575f604051631e4fbdf760e01b8152600401610988919061461a565b610acc81613978565b5f612cb5614442565b5f601281612cc6602087018761511f565b6003811115612cd757612cd7614693565b6003811115612ce857612ce8614693565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612d0f579050505050505090505f81600160028110612d6657612d6661506b565b602002015163ffffffff1611845f016020810190612d84919061511f565b90612da35760405163286c068d60e11b81526004016109889190615138565b50602084013542811015612dcd57604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612dfb5760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612e13426040890135615193565b612e1d9190614e4f565b612e279190614e4f565b905060055481108190612e50576040516313b783af60e21b815260040161098891815260200190565b5060075f612e6460808801606089016145d4565b6001600160a01b0316815260208101919091526040015f205460ff16612e9060808701606088016145d4565b90612eaf5760405163295a6a6f60e11b8152600401610988919061461a565b505f612eba86611b82565b60068054965090915085905f612ecf836155a7565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff191660011790556010909452829020805433941693909317909255601654919250612faa9190890135614e4f565b5f878152600e6020908152604090912060010191909155818652612fd09088018861511f565b85602001906003811115612fe657612fe6614693565b90816003811115612ff957612ff9614693565b905250436040808701919091528051808201825290602089019060029083908390808284375f92019190915250505060608087019190915261304190608089019089016145d4565b6001600160a01b031660a08087019190915261306290880160808901614994565b60ff1660c08087019190915261307a908801886155bf565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e0808701919091526130c7906101008901908901615601565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454613117916001600160a01b03909116903085614281565b5f600b8161312b60a08b0160808c01614994565b60ff1660ff1681526020019081526020015f20805461314990614de8565b80601f016020809104026020016040519081016040528092919081815260200182805461317590614de8565b80156131c05780601f10613197576101008083540402835291602001916131c0565b820191905f5260205f20905b8154815290600101906020018083116131a357829003601f168201915b505050505090505f8151116131e75760405162461bcd60e51b8152600401610988906150e8565b5f6131f860808a0160608b016145d4565b6001600160a01b031663fefd9a8b89858561321660a08f018f6155bf565b8f8060c0019061322691906155bf565b6040518863ffffffff1660e01b8152600401613248979695949392919061561c565b6020604051808303815f875af1158015613264573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613288919061517c565b5f818152600960205260409020549091506001600160a01b031681816132c4576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b031682816132fe576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561335c5761335c614693565b021790555060408201518160020155606082015181600301906002613382929190614560565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906133db9082615670565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906134439082615670565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b906134a9908d9089908d90600401615725565b6020604051808303815f875af11580156134c5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134e991906150ba565b61350657604051630d8dbe2560e01b815260040160405180910390fd5b61351660808c0160608d016145d4565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b604051613550929190614dc8565b60405180910390a2895f5160206159d95f395f51905f525f6001604051613578929190614e62565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff16818160068111156135b1576135b1614693565b036135d657826001826040516337e1404160e01b815260040161098893929190614e1a565b60058160068111156135ea576135ea614693565b0361360b5760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561361f5761361f614693565b0361364057604051633de16e3560e11b815260048101849052602401610988565b5f61364b8483613b32565b935090508061367057604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d8111156136b9576136b9614693565b0217905550835f5160206159d95f395f51905f528360066040516136de929190614e62565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb838560405161371892919061576a565b60405180910390a25050919050565b61372f61384e565b6001600160a01b0381161580159061375457505f546001600160a01b03828116911614155b8190613774576040516375ac4eb760e11b8152600401610988919061461a565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab090839061461a565b6001600160a01b0381165f90815260076020526040902054819060ff16156137fb5760405163b29d459560e01b8152600401610988919061461a565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab090839061461a565b33613857611688565b6001600160a01b0316146112fe573360405163118cdaa760e01b8152600401610988919061461a565b803561389f5760405163055f269d60e01b815260040160405180910390fd5b5f8160200135116138c35760405163055f269d60e01b815260040160405180910390fd5b5f8160400135116138e75760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b61396f6142c0565b610acc816142e5565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115613a1057613a10614693565b1480613a2d5750600281600d811115613a2b57613a2b614693565b145b15613a65575f5b604051908082528060200260200182016040528015613a5d578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613acb57506040513d5f823e601f3d908101601f19168201604052613ac89190810190615841565b60015b613a5d575f613a34565b613b2d83846001600160a01b031663a9059cbb8585604051602401613afb929190615906565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506142ed565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613bac573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bd0919061517c565b90506001856006811115613be657613be6614693565b148015613bf257508042115b15613c0557600180935093505050613cb3565b6002856006811115613c1957613c19614693565b148015613c265750815142115b15613c3a5760016003935093505050613cb3565b6003856006811115613c4e57613c4e614693565b148015613c5e5750816020015142115b15613c725760016006935093505050613cb3565b6004856006811115613c8657613c86614693565b148015613c965750816040015142115b15613caa576001600a935093505050613cb3565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613cff573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613d269190810190615841565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613dc5576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d919088908890869060040161591f565b5f604051808303815f87803b158015613da8575f5ffd5b505af1158015613dba573d5f5f3e3d5ffd5b505050505050505050565b825f03613e66575f858152601060205260409020546001600160a01b03168015613dfd57613dfd6001600160a01b0383168285613ad5565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613e319089908990879060040161591f565b5f604051808303815f87803b158015613e48575f5ffd5b505af1158015613e5a573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613ea657506001600160a01b03811615155b15613ee257612710613ebc61ffff841687615146565b613ec6919061515d565b92508215613ee257613ee26001600160a01b0385168285613ad5565b5f613eed8487615193565b90505f876001600160401b03811115613f0857613f08614e7d565b604051908082528060200260200182016040528015613f31578160200160208202803683370190505b5090505f613f3f898461515d565b90505f805b8a811015613f7e5782848281518110613f5f57613f5f61506b565b6020908102919091010152613f748383614e4f565b9150600101613f44565b505f613f8a8286615193565b90508015613fc7578084613f9f60018e615193565b81518110613faf57613faf61506b565b60200260200101818151613fc39190614e4f565b9052505b600154613fe1906001600160a01b038b8116911687614350565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b81526004016140259392919061597f565b5f604051808303815f87803b15801561403c575f5ffd5b505af115801561404e573d5f5f3e3d5ffd5b505060015461406c92506001600160a01b038c81169250165f614350565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d8660405161409e9291906159b4565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b81526004016140ea9392919061591f565b5f604051808303815f87803b158015614101575f5ffd5b505af1158015614113573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f828152600d602052604081205460ff169081600681111561414a5761414a614693565b0361416f57826001826040516337e1404160e01b815260040161098893929190614e1a565b600581600681111561418357614183614693565b036141a45760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156141b8576141b8614693565b036141d957604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561422257614222614693565b0217905550825f5160206159d95f395f51905f52826006604051614247929190614e62565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612c6592919061576a565b6040516001600160a01b0384811660248301528381166044830152606482018390526142ba9186918216906323b872dd90608401613afb565b50505050565b6142c86143e0565b6112fe57604051631afcd79f60e31b815260040160405180910390fd5b612c7a6142c0565b5f5f60205f8451602086015f885af18061430c576040513d5f823e3d81fd5b50505f513d91508115614323578060011415614330565b6001600160a01b0384163b155b156142ba5783604051635274afe760e01b8152600401610988919061461a565b5f836001600160a01b031663095ea7b38484604051602401614373929190615906565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506143ac84826143f9565b6142ba576143d684856001600160a01b031663095ea7b3865f604051602401613afb929190615906565b6142ba84826142ed565b5f6143e961393d565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156144385750811561442a5780600114614438565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161446a61458e565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b600183019183908215614550579160200282015f5b8382111561451e57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026144d4565b801561454e5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261451e565b505b5061455c9291506145ac565b5090565b8260028101928215614550579160200282015b82811115614550578251825591602001919060010190614573565b60405180604001604052806002906020820280368337509192915050565b5b8082111561455c575f81556001016145ad565b6001600160a01b0381168114610acc575f5ffd5b5f602082840312156145e4575f5ffd5b81356145ef816145c0565b9392505050565b5f60208284031215614606575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b80356004811061463c575f5ffd5b919050565b5f5f60408385031215614652575f5ffd5b61465b8361462e565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f60608284031215614689575f5ffd5b6145ef8383614669565b634e487b7160e01b5f52602160045260245ffd5b600e81106146b7576146b7614693565b9052565b6020810161396182846146a7565b600481106146b7576146b7614693565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152614717602082018f6146c9565b8c60408201528b6060820152614730608082018c61460d565b60ff8a1660a08201526101c060c08201525f6147506101c083018b6146d9565b61475d60e084018b61460d565b61476b61010084018a61460d565b876101208401528661014084015282810361016084015261478c81876146d9565b91505061479d61018083018561460d565b8215156101a08301529f9e505050505050505050505050505050565b805f5b60028110156142ba5781518452602093840193909101906001016147bc565b805182525f60208201516147f260208501826146c9565b5060408201516040840152606082015161480f60608501826147b9565b50608082015160a084015260a082015161482c60c085018261460d565b5060c082015160ff811660e08501525060e08201516102006101008501526148586102008501826146d9565b905061010083015161486e61012086018261460d565b5061012083015161488361014086018261460d565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526148b582826146d9565b9150506101a08301516148cc6101c086018261460d565b506101c08301518015156101e0860152613a5d565b602081525f6145ef60208301846147db565b803561463c816145c0565b5f5f5f5f5f5f5f610120888a031215614915575f5ffd5b8735614920816145c0565b96506020880135614930816145c0565b95506040880135614940816145c0565b94506060880135614950816145c0565b93506080880135614960816145c0565b925060a088013591506149768960c08a01614669565b905092959891949750929550565b803560ff8116811461463c575f5ffd5b5f602082840312156149a4575f5ffd5b6145ef82614984565b602081525f6145ef60208301846146d9565b5f5f604083850312156149d0575f5ffd5b8235915060208301356149e2816145c0565b809150509250929050565b5f5f604083850312156149fe575f5ffd5b50508035926020909101359150565b5f5f83601f840112614a1d575f5ffd5b5081356001600160401b03811115614a33575f5ffd5b602083019150836020828501011115613cb3575f5ffd5b5f5f5f60408486031215614a5c575f5ffd5b614a6584614984565b925060208401356001600160401b03811115614a7f575f5ffd5b614a8b86828701614a0d565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613961565b8215158152604081016145ef60208301846146a7565b5f5f5f5f5f60608688031215614ae3575f5ffd5b8535945060208601356001600160401b03811115614aff575f5ffd5b614b0b88828901614a0d565b90955093505060408601356001600160401b03811115614b29575f5ffd5b614b3588828901614a0d565b969995985093965092949392505050565b5f60208284031215614b56575f5ffd5b81356001600160401b03811115614b6b575f5ffd5b820161010081850312156145ef575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614bd760e084018261460d565b50610100830151614bef61010084018261ffff169052565b50610120830151614c0761012084018261ffff169052565b50610140830151614c1f61014084018261ffff169052565b50610160830151614c3761016084018261ffff169052565b50610180830151614c4f61018084018261ffff169052565b506101a0830151614c696101a084018263ffffffff169052565b506101c0830151614c836101c084018263ffffffff169052565b5092915050565b5f5f5f5f5f5f5f6080888a031215614ca0575f5ffd5b8735965060208801356001600160401b03811115614cbc575f5ffd5b614cc88a828b01614a0d565b90975095505060408801356001600160401b03811115614ce6575f5ffd5b614cf28a828b01614a0d565b90955093505060608801356001600160401b03811115614d10575f5ffd5b614d1c8a828b01614a0d565b989b979a50959850939692959293505050565b5f5f60408385031215614d40575f5ffd5b82359150614d5060208401614984565b90509250929050565b600781106146b7576146b7614693565b602081016139618284614d59565b5f6101e0828403128015614d89575f5ffd5b509092915050565b5f5f60608385031215614da2575f5ffd5b614dab8361462e565b915083606084011115614dbc575f5ffd5b50926020919091019150565b828152604060208201525f614de060408301846147db565b949350505050565b600181811c90821680614dfc57607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614e2e6020830185614d59565b614de06040830184614d59565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561396157613961614e3b565b60408101614e708285614d59565b6145ef6020830184614d59565b634e487b7160e01b5f52604160045260245ffd5b601f821115613b2d57805f5260205f20601f840160051c81016020851015614eb65750805b601f840160051c820191505b81811015614ed5575f8155600101614ec2565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b03831115614f0757614f07614e7d565b614f1b83614f158354614de8565b83614e91565b5f601f841160018114614f47575f8515614f355750838201355b614f3f8682614edc565b845550614ed5565b5f83815260208120601f198716915b82811015614f765786850135825560209485019460019092019101614f56565b5086821015614f92575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60ff84168152604060208201525f614fe8604083018486614fa4565b95945050505050565b5f8151808452602084019350602083015f5b8281101561502a5781516001600160a01b0316865260209586019590910190600101615003565b5093949350505050565b848152836020820152608060408201525f6150526080830185614ff1565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b818382375f9101908152919050565b848152836020820152606060408201525f614438606083018486614fa4565b8015158114610acc575f5ffd5b5f602082840312156150ca575f5ffd5b81516145ef816150ad565b602081525f614de0602083018486614fa4565b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f6020828403121561512f575f5ffd5b6145ef8261462e565b6020810161396182846146c9565b808202811582820484141761396157613961614e3b565b5f8261517757634e487b7160e01b5f52601260045260245ffd5b500490565b5f6020828403121561518c575f5ffd5b5051919050565b8181038181111561396157613961614e3b565b858152606060208201525f6151bf606083018688614fa4565b82810360408401526151d2818587614fa4565b98975050505050505050565b604081525f6151f1604083018688614fa4565b8281036020840152615204818587614fa4565b979650505050505050565b61ffff81168114610acc575f5ffd5b803561463c8161520f565b5f60208284031215615239575f5ffd5b81356145ef8161520f565b63ffffffff81168114610acc575f5ffd5b803561463c81615244565b5f60208284031215615270575f5ffd5b81356145ef81615244565b5f8135613961816145c0565b5f81356139618161520f565b5f813561396181615244565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201556007810161530f6152f260e0850161527b565b82546001600160a01b0319166001600160a01b0391909116178255565b61533f61531f6101008501615287565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b61536f61534f6101208501615287565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b61539f61537f6101408501615287565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6153cf6153af6101608501615287565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6153ff6153df6101808501615287565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161542b6154146101a08501615293565b825463ffffffff191663ffffffff91909116178255565b613b2d61543b6101c08501615293565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016154ae60e084016148f3565b6154bb60e084018261460d565b506154c9610100840161521e565b61ffff166101008301526154e0610120840161521e565b61ffff166101208301526154f7610140840161521e565b61ffff1661014083015261550e610160840161521e565b61ffff16610160830152615525610180840161521e565b61ffff1661018083015261553c6101a08401615255565b63ffffffff166101a08301526155556101c08401615255565b63ffffffff81166101c0840152614c83565b6040810181835f5b600281101561559e57813561558381615244565b63ffffffff168352602092830192919091019060010161556f565b50505092915050565b5f600182016155b8576155b8614e3b565b5060010190565b5f5f8335601e198436030181126155d4575f5ffd5b8301803591506001600160401b038211156155ed575f5ffd5b602001915036819003821315613cb3575f5ffd5b5f60208284031215615611575f5ffd5b81356145ef816150ad565b87815286602082015260a060408201525f61563a60a08301886146d9565b828103606084015261564d818789614fa4565b90508281036080840152615662818587614fa4565b9a9950505050505050505050565b81516001600160401b0381111561568957615689614e7d565b61569d816156978454614de8565b84614e91565b6020601f8211600181146156ca575f83156156b85750848201515b6156c28482614edc565b855550614ed5565b5f84815260208120601f198516915b828110156156f957878501518255602094850194600190920191016156d9565b508482101561571657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561575f57815163ffffffff1683526020928301929091019060010161573a565b505050949350505050565b604081016157788285614d59565b6145ef60208301846146a7565b604051601f8201601f191681016001600160401b03811182821017156157ad576157ad614e7d565b604052919050565b5f6001600160401b038211156157cd576157cd614e7d565b5060051b60200190565b5f82601f8301126157e6575f5ffd5b81516157f96157f4826157b5565b615785565b8082825260208201915060208360051b86010192508583111561581a575f5ffd5b602085015b8381101561583757805183526020928301920161581f565b5095945050505050565b5f5f60408385031215615852575f5ffd5b82516001600160401b03811115615867575f5ffd5b8301601f81018513615877575f5ffd5b80516158856157f4826157b5565b8082825260208201915060208360051b8501019250878311156158a6575f5ffd5b6020840193505b828410156158d15783516158c0816145c0565b8252602093840193909101906158ad565b8095505050505060208301516001600160401b038111156158f0575f5ffd5b6158fc858286016157d7565b9150509250929050565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f6159376060830185614ff1565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b8281101561502a578151865260209586019590910190600101615961565b6001600160a01b03841681526060602082018190525f906159a290830185614ff1565b8281036040840152614438818561594f565b604081525f6159c66040830185614ff1565b8281036020840152614fe8818561594f56fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-361d4ed525b2a26ac9b3313fd80fb3038fddef8a" + "buildInfoId": "solc-0_8_28-450dba89e3316019924fd97da52afa696f4be931" } \ 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 185e63b330..739fb88b9e 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-67d7bf420ed8ac25001394841682e83cf4523ea2" + "buildInfoId": "solc-0_8_28-a5591f76a7a8353e3d0dd83e83c16479678f73a9" } \ 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 4e550a8b39..1cc20d8da0 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -965,5 +965,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-67d7bf420ed8ac25001394841682e83cf4523ea2" + "buildInfoId": "solc-0_8_28-a5591f76a7a8353e3d0dd83e83c16479678f73a9" } \ 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 fa7cc31b58..7596014063 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -425,19 +425,6 @@ "name": "UtilizationBpsExceedsMax", "type": "error" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes[]", - "name": "e3ProgramParams", - "type": "bytes[]" - } - ], - "name": "AllowedE3ProgramsParamsSet", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -604,19 +591,6 @@ "name": "E3ProgramEnabled", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes[]", - "name": "e3ProgramParams", - "type": "bytes[]" - } - ], - "name": "E3ProgramsParamsRemoved", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -672,9 +646,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -840,6 +814,25 @@ "name": "MaxDurationSet", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "encodedParams", + "type": "bytes" + } + ], + "name": "ParamSetRegistered", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1247,9 +1240,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1320,9 +1313,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1696,19 +1689,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "_e3ProgramsParams", - "type": "bytes[]" - } - ], - "name": "removeE3ProgramsParams", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -1729,9 +1709,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1794,9 +1774,9 @@ "type": "address" }, { - "internalType": "bytes", - "name": "e3ProgramParams", - "type": "bytes" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" }, { "internalType": "bytes", @@ -1912,12 +1892,12 @@ { "inputs": [ { - "internalType": "bytes[]", - "name": "_e3ProgramsParams", - "type": "bytes[]" + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" } ], - "name": "setE3ProgramsParams", + "name": "setFeeToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1925,12 +1905,12 @@ { "inputs": [ { - "internalType": "contract IERC20", - "name": "_feeToken", - "type": "address" + "internalType": "uint256", + "name": "_maxDuration", + "type": "uint256" } ], - "name": "setFeeToken", + "name": "setMaxDuration", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1938,12 +1918,17 @@ { "inputs": [ { - "internalType": "uint256", - "name": "_maxDuration", - "type": "uint256" + "internalType": "uint8", + "name": "paramSet", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "encodedParams", + "type": "bytes" } ], - "name": "setMaxDuration", + "name": "setParamSet", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -2093,5 +2078,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-67d7bf420ed8ac25001394841682e83cf4523ea2" + "buildInfoId": "solc-0_8_28-a5591f76a7a8353e3d0dd83e83c16479678f73a9" } \ 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 ae582e7c29..a41540bdda 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-67d7bf420ed8ac25001394841682e83cf4523ea2" + "buildInfoId": "solc-0_8_28-a5591f76a7a8353e3d0dd83e83c16479678f73a9" } \ 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 6a70931d0a..bb462308d4 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1264,8 +1264,8 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613ecf806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e1461057f578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063e59e469514610524578063e6745e1314610537578063e82f3b701461054a578063ebf0c7171461055d578063f165053614610565575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104bc578063ca2869a0146104cd578063cd6dc687146104ec578063da881e5a146104ff578063dbb06c9314610512575f5ffd5b80639f0f874a1461044e578063a016493014610457578063a8a4d69b14610477578063bff232c11461048a578063c2b40ae41461049d575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103ce5780638da5cb5b146103e45780638e5ce3ad146103ec5780639015d371146103ff5780639a7a2ffc14610412575f5ffd5b8063715018a6146103475780637c92f5241461034f578063858142431461037c5780638a78bb151461039c5780638cb89ecb146103af575f5ffd5b80632e7b716d116102075780632e7b716d146102d95780634d6861a6146102ec57806350e6d94c146102ff5780635d5047761461032157806370e36bbe14610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610295578063291a691b146102b6575b5f5ffd5b6102566102513660046132aa565b61065a565b005b6102566102663660046132c5565b6107a6565b61027e6102793660046132c5565b6107e9565b60405161028c92919061334f565b60405180910390f35b6102a86102a33660046132c5565b610993565b60405190815260200161028c565b6102c96102c436600461337c565b6109df565b604051901515815260200161028c565b6102c96102e73660046132aa565b610bb9565b6102c96102fa3660046132c5565b610c6c565b6102c961030d3660046132aa565b60066020525f908152604090205460ff1681565b6102c961032f3660046133b5565b610cab565b6102566103423660046132aa565b610cef565b610256610d65565b61036261035d3660046133e3565b610d78565b6040805192835263ffffffff90911660208301520161028c565b60015461038f906001600160a01b031681565b60405161028c9190613418565b6102566103aa3660046132aa565b610f1f565b6102a86103bd3660046132c5565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a8565b61038f61105d565b600b5461038f906001600160a01b031681565b6102c961040d3660046132aa565b61108b565b6104386104203660046132aa565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102a860035481565b61046a6104653660046132c5565b6110a8565b60405161028c919061342c565b6102c96104853660046133b5565b61113e565b6102566104983660046132aa565b611182565b6102a86104ab3660046132c5565b60086020525f908152604090205481565b6001546001600160a01b031661038f565b6102a86104db3660046132c5565b5f9081526008602052604090205490565b6102566104fa36600461343e565b6111d3565b6102c961050d3660046132c5565b611330565b5f5461038f906001600160a01b031681565b6102566105323660046132aa565b61160a565b610256610545366004613468565b611682565b6102a86105583660046132c5565b611845565b6102a8611876565b61056d601481565b60405160ff909116815260200161028c565b61025661058d3660046134cc565b611888565b6102566105a03660046132aa565b611b7a565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed3660046132c5565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a860025481565b61066261105d565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b18161108b565b81906106da576040516381e5828960e01b81526004016106d19190613418565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611bb4565b6001600160a01b0382165f908152600660205260408120805460ff191690556002805491610735836135e6565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611e56565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b03811115610820576108206135fb565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b03811115610864576108646135fb565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b161360f565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613623565b03610980578088848151811061090f5761090f61360f565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109675761096761360f565b60209081029190910101528261097c81613637565b9350505b50600101610893565b5050505050915091565b5f818152600a6020526040812081815460ff1660038111156109b7576109b7613623565b036109d557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a0a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a2e57610a2e613623565b14610a4c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a93573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab7919061364f565b905080610aca6040860160208701613679565b63ffffffff161115610ae26040860160208701613679565b829091610b10576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610b379042613692565b6003830155610b4b600583018560026131e1565b50610b54611876565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ba5928a928a92916136a5565b60405180910390a250600195945050505050565b5f610bc38261108b565b610bce57505f919050565b6001546001600160a01b0316610bf7576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c27908590600401613418565b602060405180830381865afa158015610c42573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c669190613704565b92915050565b5f818152600a602052604081206001815460ff166003811115610c9157610c91613623565b14610c9e57505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610ce757610ce7613623565b149392505050565b610cf7611e56565b6001600160a01b038116610d1e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610d6d611e56565b610d765f611e88565b565b600b545f9081906001600160a01b03163314610da75760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610dcc57610dcc613623565b14610dea57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610e2a57610e2a613623565b14610e3a57600a01549150610f17565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610e6e836135e6565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610ebf929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f2761105d565b6001600160a01b0316336001600160a01b03161480610f5057506001546001600160a01b031633145b610f6d57604051632864c4e160e01b815260040160405180910390fd5b610f768161108b565b61105a5760048054600160281b900464ffffffffff1690610fa0906001600160a01b038416611ef8565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610ff183613637565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906110db576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561113157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611113575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561117957611179613623565b14159392505050565b61118a611e56565b6001600160a01b0381166111b15760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6111dc6120ce565b805490915060ff600160401b82041615906001600160401b03165f811580156112025750825b90505f826001600160401b0316600114801561121d5750303b155b90508115801561122b575080155b156112495760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561127357845460ff60401b1916600160401b1785555b6001600160a01b03871661129a5760405163d92e233d60e01b815260040160405180910390fd5b6112a3336120f6565b6112af60046014612107565b6112b8866107a6565b6112c061105d565b6001600160a01b0316876001600160a01b0316146112e1576112e187611b7a565b831561132757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561135457611354613623565b0361137257604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561138a5761138a613623565b146113a857604051631860f69960e31b815260040160405180910390fd5b806003015442116113cc57604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806114b1578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b038111156114e1576114e16135fb565b60405190808252806020026020018201604052801561150a578160200160208202803683370190505b5090505f5b8281101561157c57846008015f8660060183815481106115315761153161360f565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106115695761156961360f565b602090810291909101015260010161150f565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b1580156115bf575f5ffd5b505af11580156115d1573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ba592919061371d565b611612611e56565b6001600160a01b0381166116395760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156116a6576116a6613623565b036116c457604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116dc576116dc613623565b146116fa57604051631860f69960e31b815260040160405180910390fd5b806003015442111561171f57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156117515760405163257309f160e11b815260040160405180910390fd5b61175a33610bb9565b6117775760405163149fbcfd60e11b815260040160405180910390fd5b611782338385612186565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff1916600117905590915061180190839083612357565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611871576040516322e679e360e11b815260040160405180910390fd5b919050565b5f61188360046014612558565b905090565b5f898152600a602052604090206002815460ff1660038111156118ad576118ad613623565b146118cb57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156118ee5760405163632a22bb60e01b815260040160405180910390fd5b600681015488146119375760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b5f61194485870187613874565b9150505f81511161198e5760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106d1565b5f816001835161199e9190613917565b815181106119ae576119ae61360f565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016119fa91815260200190565b5f60405180830381865afa158015611a14573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611a3b91908101906139fc565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611a75908b908b908b908b90600401613b9b565b602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061364f565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015611b13575f5ffd5b505af1158015611b25573d5f5f3e3d5ffd5b505050508c7f49ac1dd411942113d1c5e6799c6379ce341afe85a4175fb562cf2a5fb886c27d8d8d8d8d8d8d604051611b6396959493929190613bcc565b60405180910390a250505050505050505050505050565b611b82611e56565b6001600160a01b038116611bab575f604051631e4fbdf760e01b81526004016106d19190613418565b61105a81611e88565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611bf35760405162461bcd60e51b81526004016106d190613c45565b825464ffffffffff600160281b90910481169082168111611c515760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611c648488612651565b64ffffffffff1681526020019081526020015f20819055505f816001611c8a9190613c8f565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611cbf5750611e4e565b600185165f03611d86575f611cde83611cd9886001613ca8565b612651565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d3f91600401613cc5565b602060405180830381865af4158015611d5a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d7e919061364f565b935050611e3a565b5f611d9683611cd9600189613cf5565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611df791600401613cc5565b602060405180830381865af4158015611e12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e36919061364f565b9350505b50647fffffffff600194851c169301611c54565b505050505050565b33611e5f61105d565b6001600160a01b031614610d76573360405163118cdaa760e01b81526004016106d19190613418565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611f475760405162461bcd60e51b81526004016106d190613c45565b825464ffffffffff90811690821610611f9a5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611fa5816001613ca8565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611fdc8487612651565b64ffffffffff16815260208101919091526040015f205560018316156120c7575f61200c82611cd9600187613cf5565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe9161206d91600401613cc5565b602060405180830381865af4158015612088573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120ac919061364f565b647fffffffff600195861c1694909350919091019050611fcc565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c66565b6120fe61266e565b61105a81612693565b602060ff821611156121555760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b612166600160ff831681901b613917565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121a65760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166121cf576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161220591613917565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561224c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612270919061364f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e7919061364f565b90505f81116123095760405163aeaddff160e01b815260040160405180910390fd5b5f6123148284613d12565b90505f81116123365760405163149fbcfd60e11b815260040160405180910390fd5b808611156113275760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156123d557508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612551565b5f5f90505f876008015f855f815481106123f1576123f161360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612479575f896008015f87848154811061243b5761243b61360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612470578092508193505b5060010161241a565b5080861061248d575f945050505050612551565b5f886009015f8685815481106124a5576124a561360f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156124e2576124e2613623565b0217905550868483815481106124fa576124fa61360f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116125ab5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156125cf5760405162461bcd60e51b81526004016106d190613d31565b8254600160281b900464ffffffffff16806125ee60ff85166002613e82565b64ffffffffff16101561263e5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b61264984828561269b565b949350505050565b5f8161266460ff851663ffffffff613e9b565b6125519190613ca8565b612676612763565b610d7657604051631afcd79f60e31b815260040160405180910390fd5b611b8261266e565b5f602060ff831611156126c05760405162461bcd60e51b81526004016106d190613d31565b8264ffffffffff165f036126de576126d78261277c565b9050612551565b5f6126ea836001613c8f565b60ff166001600160401b03811115612704576127046135fb565b60405190808252806020026020018201604052801561272d578160200160208202803683370190505b50905061273c85858584612e16565b808360ff16815181106127515761275161360f565b60200260200101519150509392505050565b5f61276c6120ce565b54600160401b900460ff16919050565b5f8160ff165f0361278e57505f919050565b8160ff166001036127c057507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036127f257507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361282457507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361285657507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361288857507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036128ba57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036128ec57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361291e57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361295057507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361298257507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b036129b457507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036129e657507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a1857507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612a4a57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612a7c57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612aae57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612ae057507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b1257507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b4457507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612b7657507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612ba857507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612bda57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c0c57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c3e57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612c7057507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612ca257507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612cd457507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d0657507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d3857507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612d6a57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612d9c57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612dce57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e3a5760405162461bcd60e51b81526004016106d190613d31565b5f8364ffffffffff1611612e9e5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612eaa600185613cf5565b9050600181165f03612efd57846001015f612ec55f84612651565b64ffffffffff1681526020019081526020015f2054825f81518110612eec57612eec61360f565b602002602001018181525050612f25565b612f065f61277c565b825f81518110612f1857612f1861360f565b6020026020010181815250505b5f5b8360ff168160ff161015611e4e57600182165f0361301d5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612f7957612f7961360f565b60200260200101518152602001612f8f8561277c565b8152506040518263ffffffff1660e01b8152600401612fae9190613cc5565b602060405180830381865af4158015612fc9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fed919061364f565b83612ff9836001613c8f565b60ff168151811061300c5761300c61360f565b6020026020010181815250506131ce565b5f613029826001613c8f565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156130cb575f876001015f61308085600161306f9190613c8f565b60018864ffffffffff16901c612651565b64ffffffffff1681526020019081526020015f2054905080858460016130a69190613c8f565b60ff16815181106130b9576130b961360f565b602002602001018181525050506131cc565b5f876001015f6130e285600188611cd99190613cf5565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff16815181106131395761313961360f565b60200260200101518152506040518263ffffffff1660e01b81526004016131609190613cc5565b602060405180830381865af415801561317b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061319f919061364f565b856131ab856001613c8f565b60ff16815181106131be576131be61360f565b602002602001018181525050505b505b647fffffffff600192831c169101612f27565b600183019183908215613272579160200282015f5b8382111561324057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026131f6565b80156132705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613240565b505b5061327e929150613282565b5090565b5b8082111561327e575f8155600101613283565b6001600160a01b038116811461105a575f5ffd5b5f602082840312156132ba575f5ffd5b813561255181613296565b5f602082840312156132d5575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b828110156133155781516001600160a01b03168652602095860195909101906001016132ee565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613315578151865260209586019590910190600101613331565b604081525f61336160408301856132dc565b8281036020840152613373818561331f565b95945050505050565b5f5f5f6080848603121561338e575f5ffd5b8335925060208401359150608084018510156133a8575f5ffd5b6040840190509250925092565b5f5f604083850312156133c6575f5ffd5b8235915060208301356133d881613296565b809150509250929050565b5f5f5f606084860312156133f5575f5ffd5b83359250602084013561340781613296565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61255160208301846132dc565b5f5f6040838503121561344f575f5ffd5b823561345a81613296565b946020939093013593505050565b5f5f60408385031215613479575f5ffd5b50508035926020909101359150565b5f5f83601f840112613498575f5ffd5b5081356001600160401b038111156134ae575f5ffd5b6020830191508360208285010111156134c5575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c0312156134e4575f5ffd5b8935985060208a01356001600160401b03811115613500575f5ffd5b8a01601f81018c13613510575f5ffd5b80356001600160401b03811115613525575f5ffd5b8c60208260051b8401011115613539575f5ffd5b6020919091019850965060408a01356001600160401b0381111561355b575f5ffd5b6135678c828d01613488565b90975095505060608a01356001600160401b03811115613585575f5ffd5b6135918c828d01613488565b90955093505060808a01356001600160401b038111156135af575f5ffd5b6135bb8c828d01613488565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f816135f4576135f46135d2565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60018201613648576136486135d2565b5060010190565b5f6020828403121561365f575f5ffd5b5051919050565b803563ffffffff81168114611871575f5ffd5b5f60208284031215613689575f5ffd5b61255182613666565b80820180821115610c6657610c666135d2565b84815260a0810160208201855f5b60028110156136e05763ffffffff6136ca83613666565b16835260209283019291909101906001016136b3565b50505060608201939093526080015292915050565b80518015158114611871575f5ffd5b5f60208284031215613714575f5ffd5b612551826136f5565b604080825283549082018190525f8481526020812090916060840190835b818110156137625783546001600160a01b031683526001938401936020909301920161373b565b50508381036020850152613776818661331f565b9695505050505050565b6040516101e081016001600160401b03811182821017156137a3576137a36135fb565b60405290565b604051601f8201601f191681016001600160401b03811182821017156137d1576137d16135fb565b604052919050565b5f6001600160401b038211156137f1576137f16135fb565b50601f01601f191660200190565b5f82601f83011261380e575f5ffd5b81356001600160401b03811115613827576138276135fb565b8060051b613837602082016137a9565b91825260208185018101929081019086841115613852575f5ffd5b6020860192505b83831015613776578235825260209283019290910190613859565b5f5f60408385031215613885575f5ffd5b82356001600160401b0381111561389a575f5ffd5b8301601f810185136138aa575f5ffd5b80356138bd6138b8826137d9565b6137a9565b8181528660208385010111156138d1575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b03811115613901575f5ffd5b61390d858286016137ff565b9150509250929050565b81810381811115610c6657610c666135d2565b805160048110611871575f5ffd5b5f82601f830112613947575f5ffd5b604080519081016001600160401b0381118282101715613969576139696135fb565b806040525080604084018581111561397f575f5ffd5b845b81811015613999578051835260209283019201613981565b509195945050505050565b805161187181613296565b5f82601f8301126139be575f5ffd5b81516139cc6138b8826137d9565b8181528460208386010111156139e0575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613a0c575f5ffd5b81516001600160401b03811115613a21575f5ffd5b82016102008185031215613a33575f5ffd5b613a3b613780565b81518152613a4b6020830161392a565b602082015260408281015190820152613a678560608401613938565b606082015260a08201516080820152613a8260c083016139a4565b60a082015260e08201516001600160401b03811115613a9f575f5ffd5b613aab868285016139af565b60c0830152506101008201516001600160401b03811115613aca575f5ffd5b613ad6868285016139af565b60e083015250613ae961012083016139a4565b610100820152613afc61014083016139a4565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613b32575f5ffd5b613b3e868285016139af565b61018083015250613b526101c083016139a4565b6101a0820152613b656101e083016136f5565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613bae604083018688613b73565b8281036020840152613bc1818587613b73565b979650505050505050565b606080825281018690525f8760808301825b89811015613c0e578235613bf181613296565b6001600160a01b0316825260209283019290910190600101613bde565b508381036020850152613c2281888a613b73565b9150508281036040840152613c38818587613b73565b9998505050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610c6657610c666135d2565b64ffffffffff8181168382160190811115610c6657610c666135d2565b6040810181835f5b6002811015613cec578151835260209283019290910190600101613ccd565b50505092915050565b64ffffffffff8281168282160390811115610c6657610c666135d2565b5f82613d2c57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f1757808504811115613d9357613d936135d2565b6001841615613da157908102905b60019390931c928002613d78565b5f82613dbd57506001610c66565b81613dc957505f610c66565b8160018114613ddf5760028114613de957613e1b565b6001915050610c66565b60ff841115613dfa57613dfa6135d2565b6001841b915064ffffffffff821115613e1557613e156135d2565b50610c66565b5060208310610133831016604e8410600b8410161715613e53575081810a64ffffffffff811115613e4e57613e4e6135d2565b610c66565b613e6364ffffffffff8484613d74565b8064ffffffffff04821115613e7a57613e7a6135d2565b029392505050565b5f61255164ffffffffff841664ffffffffff8416613daf565b64ffffffffff8181168382160290811690818114613ebb57613ebb6135d2565b509291505056fea164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e1461057f578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063e59e469514610524578063e6745e1314610537578063e82f3b701461054a578063ebf0c7171461055d578063f165053614610565575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104bc578063ca2869a0146104cd578063cd6dc687146104ec578063da881e5a146104ff578063dbb06c9314610512575f5ffd5b80639f0f874a1461044e578063a016493014610457578063a8a4d69b14610477578063bff232c11461048a578063c2b40ae41461049d575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103ce5780638da5cb5b146103e45780638e5ce3ad146103ec5780639015d371146103ff5780639a7a2ffc14610412575f5ffd5b8063715018a6146103475780637c92f5241461034f578063858142431461037c5780638a78bb151461039c5780638cb89ecb146103af575f5ffd5b80632e7b716d116102075780632e7b716d146102d95780634d6861a6146102ec57806350e6d94c146102ff5780635d5047761461032157806370e36bbe14610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610295578063291a691b146102b6575b5f5ffd5b6102566102513660046132aa565b61065a565b005b6102566102663660046132c5565b6107a6565b61027e6102793660046132c5565b6107e9565b60405161028c92919061334f565b60405180910390f35b6102a86102a33660046132c5565b610993565b60405190815260200161028c565b6102c96102c436600461337c565b6109df565b604051901515815260200161028c565b6102c96102e73660046132aa565b610bb9565b6102c96102fa3660046132c5565b610c6c565b6102c961030d3660046132aa565b60066020525f908152604090205460ff1681565b6102c961032f3660046133b5565b610cab565b6102566103423660046132aa565b610cef565b610256610d65565b61036261035d3660046133e3565b610d78565b6040805192835263ffffffff90911660208301520161028c565b60015461038f906001600160a01b031681565b60405161028c9190613418565b6102566103aa3660046132aa565b610f1f565b6102a86103bd3660046132c5565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a8565b61038f61105d565b600b5461038f906001600160a01b031681565b6102c961040d3660046132aa565b61108b565b6104386104203660046132aa565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102a860035481565b61046a6104653660046132c5565b6110a8565b60405161028c919061342c565b6102c96104853660046133b5565b61113e565b6102566104983660046132aa565b611182565b6102a86104ab3660046132c5565b60086020525f908152604090205481565b6001546001600160a01b031661038f565b6102a86104db3660046132c5565b5f9081526008602052604090205490565b6102566104fa36600461343e565b6111d3565b6102c961050d3660046132c5565b611330565b5f5461038f906001600160a01b031681565b6102566105323660046132aa565b61160a565b610256610545366004613468565b611682565b6102a86105583660046132c5565b611845565b6102a8611876565b61056d601481565b60405160ff909116815260200161028c565b61025661058d3660046134cc565b611888565b6102566105a03660046132aa565b611b7a565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed3660046132c5565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a860025481565b61066261105d565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b18161108b565b81906106da576040516381e5828960e01b81526004016106d19190613418565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611bb4565b6001600160a01b0382165f908152600660205260408120805460ff191690556002805491610735836135e6565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611e56565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b03811115610820576108206135fb565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b03811115610864576108646135fb565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b161360f565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613623565b03610980578088848151811061090f5761090f61360f565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109675761096761360f565b60209081029190910101528261097c81613637565b9350505b50600101610893565b5050505050915091565b5f818152600a6020526040812081815460ff1660038111156109b7576109b7613623565b036109d557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a0a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a2e57610a2e613623565b14610a4c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a93573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab7919061364f565b905080610aca6040860160208701613679565b63ffffffff161115610ae26040860160208701613679565b829091610b10576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610b379042613692565b6003830155610b4b600583018560026131e1565b50610b54611876565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ba5928a928a92916136a5565b60405180910390a250600195945050505050565b5f610bc38261108b565b610bce57505f919050565b6001546001600160a01b0316610bf7576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c27908590600401613418565b602060405180830381865afa158015610c42573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c669190613704565b92915050565b5f818152600a602052604081206001815460ff166003811115610c9157610c91613623565b14610c9e57505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610ce757610ce7613623565b149392505050565b610cf7611e56565b6001600160a01b038116610d1e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610d6d611e56565b610d765f611e88565b565b600b545f9081906001600160a01b03163314610da75760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610dcc57610dcc613623565b14610dea57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610e2a57610e2a613623565b14610e3a57600a01549150610f17565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610e6e836135e6565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610ebf929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f2761105d565b6001600160a01b0316336001600160a01b03161480610f5057506001546001600160a01b031633145b610f6d57604051632864c4e160e01b815260040160405180910390fd5b610f768161108b565b61105a5760048054600160281b900464ffffffffff1690610fa0906001600160a01b038416611ef8565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610ff183613637565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906110db576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561113157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611113575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561117957611179613623565b14159392505050565b61118a611e56565b6001600160a01b0381166111b15760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6111dc6120ce565b805490915060ff600160401b82041615906001600160401b03165f811580156112025750825b90505f826001600160401b0316600114801561121d5750303b155b90508115801561122b575080155b156112495760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561127357845460ff60401b1916600160401b1785555b6001600160a01b03871661129a5760405163d92e233d60e01b815260040160405180910390fd5b6112a3336120f6565b6112af60046014612107565b6112b8866107a6565b6112c061105d565b6001600160a01b0316876001600160a01b0316146112e1576112e187611b7a565b831561132757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561135457611354613623565b0361137257604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561138a5761138a613623565b146113a857604051631860f69960e31b815260040160405180910390fd5b806003015442116113cc57604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806114b1578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b038111156114e1576114e16135fb565b60405190808252806020026020018201604052801561150a578160200160208202803683370190505b5090505f5b8281101561157c57846008015f8660060183815481106115315761153161360f565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106115695761156961360f565b602090810291909101015260010161150f565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b1580156115bf575f5ffd5b505af11580156115d1573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ba592919061371d565b611612611e56565b6001600160a01b0381166116395760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156116a6576116a6613623565b036116c457604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116dc576116dc613623565b146116fa57604051631860f69960e31b815260040160405180910390fd5b806003015442111561171f57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156117515760405163257309f160e11b815260040160405180910390fd5b61175a33610bb9565b6117775760405163149fbcfd60e11b815260040160405180910390fd5b611782338385612186565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff1916600117905590915061180190839083612357565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611871576040516322e679e360e11b815260040160405180910390fd5b919050565b5f61188360046014612558565b905090565b5f898152600a602052604090206002815460ff1660038111156118ad576118ad613623565b146118cb57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156118ee5760405163632a22bb60e01b815260040160405180910390fd5b600681015488146119375760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b5f61194485870187613874565b9150505f81511161198e5760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106d1565b5f816001835161199e9190613917565b815181106119ae576119ae61360f565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016119fa91815260200190565b5f60405180830381865afa158015611a14573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611a3b91908101906139fc565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611a75908b908b908b908b90600401613b9b565b602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061364f565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015611b13575f5ffd5b505af1158015611b25573d5f5f3e3d5ffd5b505050508c7f49ac1dd411942113d1c5e6799c6379ce341afe85a4175fb562cf2a5fb886c27d8d8d8d8d8d8d604051611b6396959493929190613bcc565b60405180910390a250505050505050505050505050565b611b82611e56565b6001600160a01b038116611bab575f604051631e4fbdf760e01b81526004016106d19190613418565b61105a81611e88565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611bf35760405162461bcd60e51b81526004016106d190613c45565b825464ffffffffff600160281b90910481169082168111611c515760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611c648488612651565b64ffffffffff1681526020019081526020015f20819055505f816001611c8a9190613c8f565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611cbf5750611e4e565b600185165f03611d86575f611cde83611cd9886001613ca8565b612651565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d3f91600401613cc5565b602060405180830381865af4158015611d5a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d7e919061364f565b935050611e3a565b5f611d9683611cd9600189613cf5565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611df791600401613cc5565b602060405180830381865af4158015611e12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e36919061364f565b9350505b50647fffffffff600194851c169301611c54565b505050505050565b33611e5f61105d565b6001600160a01b031614610d76573360405163118cdaa760e01b81526004016106d19190613418565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611f475760405162461bcd60e51b81526004016106d190613c45565b825464ffffffffff90811690821610611f9a5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611fa5816001613ca8565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611fdc8487612651565b64ffffffffff16815260208101919091526040015f205560018316156120c7575f61200c82611cd9600187613cf5565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe9161206d91600401613cc5565b602060405180830381865af4158015612088573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120ac919061364f565b647fffffffff600195861c1694909350919091019050611fcc565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c66565b6120fe61266e565b61105a81612693565b602060ff821611156121555760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b612166600160ff831681901b613917565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121a65760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166121cf576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161220591613917565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561224c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612270919061364f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e7919061364f565b90505f81116123095760405163aeaddff160e01b815260040160405180910390fd5b5f6123148284613d12565b90505f81116123365760405163149fbcfd60e11b815260040160405180910390fd5b808611156113275760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156123d557508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612551565b5f5f90505f876008015f855f815481106123f1576123f161360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612479575f896008015f87848154811061243b5761243b61360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612470578092508193505b5060010161241a565b5080861061248d575f945050505050612551565b5f886009015f8685815481106124a5576124a561360f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156124e2576124e2613623565b0217905550868483815481106124fa576124fa61360f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116125ab5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156125cf5760405162461bcd60e51b81526004016106d190613d31565b8254600160281b900464ffffffffff16806125ee60ff85166002613e82565b64ffffffffff16101561263e5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b61264984828561269b565b949350505050565b5f8161266460ff851663ffffffff613e9b565b6125519190613ca8565b612676612763565b610d7657604051631afcd79f60e31b815260040160405180910390fd5b611b8261266e565b5f602060ff831611156126c05760405162461bcd60e51b81526004016106d190613d31565b8264ffffffffff165f036126de576126d78261277c565b9050612551565b5f6126ea836001613c8f565b60ff166001600160401b03811115612704576127046135fb565b60405190808252806020026020018201604052801561272d578160200160208202803683370190505b50905061273c85858584612e16565b808360ff16815181106127515761275161360f565b60200260200101519150509392505050565b5f61276c6120ce565b54600160401b900460ff16919050565b5f8160ff165f0361278e57505f919050565b8160ff166001036127c057507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036127f257507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361282457507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361285657507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361288857507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036128ba57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036128ec57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361291e57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361295057507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361298257507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b036129b457507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036129e657507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a1857507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612a4a57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612a7c57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612aae57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612ae057507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b1257507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b4457507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612b7657507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612ba857507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612bda57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c0c57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c3e57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612c7057507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612ca257507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612cd457507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d0657507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d3857507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612d6a57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612d9c57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612dce57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e3a5760405162461bcd60e51b81526004016106d190613d31565b5f8364ffffffffff1611612e9e5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612eaa600185613cf5565b9050600181165f03612efd57846001015f612ec55f84612651565b64ffffffffff1681526020019081526020015f2054825f81518110612eec57612eec61360f565b602002602001018181525050612f25565b612f065f61277c565b825f81518110612f1857612f1861360f565b6020026020010181815250505b5f5b8360ff168160ff161015611e4e57600182165f0361301d5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612f7957612f7961360f565b60200260200101518152602001612f8f8561277c565b8152506040518263ffffffff1660e01b8152600401612fae9190613cc5565b602060405180830381865af4158015612fc9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fed919061364f565b83612ff9836001613c8f565b60ff168151811061300c5761300c61360f565b6020026020010181815250506131ce565b5f613029826001613c8f565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156130cb575f876001015f61308085600161306f9190613c8f565b60018864ffffffffff16901c612651565b64ffffffffff1681526020019081526020015f2054905080858460016130a69190613c8f565b60ff16815181106130b9576130b961360f565b602002602001018181525050506131cc565b5f876001015f6130e285600188611cd99190613cf5565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff16815181106131395761313961360f565b60200260200101518152506040518263ffffffff1660e01b81526004016131609190613cc5565b602060405180830381865af415801561317b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061319f919061364f565b856131ab856001613c8f565b60ff16815181106131be576131be61360f565b602002602001018181525050505b505b647fffffffff600192831c169101612f27565b600183019183908215613272579160200282015f5b8382111561324057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026131f6565b80156132705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613240565b505b5061327e929150613282565b5090565b5b8082111561327e575f8155600101613283565b6001600160a01b038116811461105a575f5ffd5b5f602082840312156132ba575f5ffd5b813561255181613296565b5f602082840312156132d5575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b828110156133155781516001600160a01b03168652602095860195909101906001016132ee565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613315578151865260209586019590910190600101613331565b604081525f61336160408301856132dc565b8281036020840152613373818561331f565b95945050505050565b5f5f5f6080848603121561338e575f5ffd5b8335925060208401359150608084018510156133a8575f5ffd5b6040840190509250925092565b5f5f604083850312156133c6575f5ffd5b8235915060208301356133d881613296565b809150509250929050565b5f5f5f606084860312156133f5575f5ffd5b83359250602084013561340781613296565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61255160208301846132dc565b5f5f6040838503121561344f575f5ffd5b823561345a81613296565b946020939093013593505050565b5f5f60408385031215613479575f5ffd5b50508035926020909101359150565b5f5f83601f840112613498575f5ffd5b5081356001600160401b038111156134ae575f5ffd5b6020830191508360208285010111156134c5575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c0312156134e4575f5ffd5b8935985060208a01356001600160401b03811115613500575f5ffd5b8a01601f81018c13613510575f5ffd5b80356001600160401b03811115613525575f5ffd5b8c60208260051b8401011115613539575f5ffd5b6020919091019850965060408a01356001600160401b0381111561355b575f5ffd5b6135678c828d01613488565b90975095505060608a01356001600160401b03811115613585575f5ffd5b6135918c828d01613488565b90955093505060808a01356001600160401b038111156135af575f5ffd5b6135bb8c828d01613488565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f816135f4576135f46135d2565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60018201613648576136486135d2565b5060010190565b5f6020828403121561365f575f5ffd5b5051919050565b803563ffffffff81168114611871575f5ffd5b5f60208284031215613689575f5ffd5b61255182613666565b80820180821115610c6657610c666135d2565b84815260a0810160208201855f5b60028110156136e05763ffffffff6136ca83613666565b16835260209283019291909101906001016136b3565b50505060608201939093526080015292915050565b80518015158114611871575f5ffd5b5f60208284031215613714575f5ffd5b612551826136f5565b604080825283549082018190525f8481526020812090916060840190835b818110156137625783546001600160a01b031683526001938401936020909301920161373b565b50508381036020850152613776818661331f565b9695505050505050565b6040516101e081016001600160401b03811182821017156137a3576137a36135fb565b60405290565b604051601f8201601f191681016001600160401b03811182821017156137d1576137d16135fb565b604052919050565b5f6001600160401b038211156137f1576137f16135fb565b50601f01601f191660200190565b5f82601f83011261380e575f5ffd5b81356001600160401b03811115613827576138276135fb565b8060051b613837602082016137a9565b91825260208185018101929081019086841115613852575f5ffd5b6020860192505b83831015613776578235825260209283019290910190613859565b5f5f60408385031215613885575f5ffd5b82356001600160401b0381111561389a575f5ffd5b8301601f810185136138aa575f5ffd5b80356138bd6138b8826137d9565b6137a9565b8181528660208385010111156138d1575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b03811115613901575f5ffd5b61390d858286016137ff565b9150509250929050565b81810381811115610c6657610c666135d2565b805160048110611871575f5ffd5b5f82601f830112613947575f5ffd5b604080519081016001600160401b0381118282101715613969576139696135fb565b806040525080604084018581111561397f575f5ffd5b845b81811015613999578051835260209283019201613981565b509195945050505050565b805161187181613296565b5f82601f8301126139be575f5ffd5b81516139cc6138b8826137d9565b8181528460208386010111156139e0575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613a0c575f5ffd5b81516001600160401b03811115613a21575f5ffd5b82016102008185031215613a33575f5ffd5b613a3b613780565b81518152613a4b6020830161392a565b602082015260408281015190820152613a678560608401613938565b606082015260a08201516080820152613a8260c083016139a4565b60a082015260e08201516001600160401b03811115613a9f575f5ffd5b613aab868285016139af565b60c0830152506101008201516001600160401b03811115613aca575f5ffd5b613ad6868285016139af565b60e083015250613ae961012083016139a4565b610100820152613afc61014083016139a4565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613b32575f5ffd5b613b3e868285016139af565b61018083015250613b526101c083016139a4565b6101a0820152613b656101e083016136f5565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613bae604083018688613b73565b8281036020840152613bc1818587613b73565b979650505050505050565b606080825281018690525f8760808301825b89811015613c0e578235613bf181613296565b6001600160a01b0316825260209283019290910190600101613bde565b508381036020850152613c2281888a613b73565b9150508281036040840152613c38818587613b73565b9998505050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610c6657610c666135d2565b64ffffffffff8181168382160190811115610c6657610c666135d2565b6040810181835f5b6002811015613cec578151835260209283019290910190600101613ccd565b50505092915050565b64ffffffffff8281168282160390811115610c6657610c666135d2565b5f82613d2c57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f1757808504811115613d9357613d936135d2565b6001841615613da157908102905b60019390931c928002613d78565b5f82613dbd57506001610c66565b81613dc957505f610c66565b8160018114613ddf5760028114613de957613e1b565b6001915050610c66565b60ff841115613dfa57613dfa6135d2565b6001841b915064ffffffffff821115613e1557613e156135d2565b50610c66565b5060208310610133831016604e8410600b8410161715613e53575081810a64ffffffffff811115613e4e57613e4e6135d2565b610c66565b613e6364ffffffffff8484613d74565b8064ffffffffff04821115613e7a57613e7a6135d2565b029392505050565b5f61255164ffffffffff841664ffffffffff8416613daf565b64ffffffffff8181168382160290811690818114613ebb57613ebb6135d2565b509291505056fea164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613ec6806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e1461057f578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063e59e469514610524578063e6745e1314610537578063e82f3b701461054a578063ebf0c7171461055d578063f165053614610565575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104bc578063ca2869a0146104cd578063cd6dc687146104ec578063da881e5a146104ff578063dbb06c9314610512575f5ffd5b80639f0f874a1461044e578063a016493014610457578063a8a4d69b14610477578063bff232c11461048a578063c2b40ae41461049d575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103ce5780638da5cb5b146103e45780638e5ce3ad146103ec5780639015d371146103ff5780639a7a2ffc14610412575f5ffd5b8063715018a6146103475780637c92f5241461034f578063858142431461037c5780638a78bb151461039c5780638cb89ecb146103af575f5ffd5b80632e7b716d116102075780632e7b716d146102d95780634d6861a6146102ec57806350e6d94c146102ff5780635d5047761461032157806370e36bbe14610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610295578063291a691b146102b6575b5f5ffd5b6102566102513660046132aa565b61065a565b005b6102566102663660046132c5565b6107a6565b61027e6102793660046132c5565b6107e9565b60405161028c92919061334f565b60405180910390f35b6102a86102a33660046132c5565b610993565b60405190815260200161028c565b6102c96102c436600461337c565b6109df565b604051901515815260200161028c565b6102c96102e73660046132aa565b610bb9565b6102c96102fa3660046132c5565b610c6c565b6102c961030d3660046132aa565b60066020525f908152604090205460ff1681565b6102c961032f3660046133b5565b610cab565b6102566103423660046132aa565b610cef565b610256610d65565b61036261035d3660046133e3565b610d78565b6040805192835263ffffffff90911660208301520161028c565b60015461038f906001600160a01b031681565b60405161028c9190613418565b6102566103aa3660046132aa565b610f1f565b6102a86103bd3660046132c5565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a8565b61038f61105d565b600b5461038f906001600160a01b031681565b6102c961040d3660046132aa565b61108b565b6104386104203660046132aa565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102a860035481565b61046a6104653660046132c5565b6110a8565b60405161028c919061342c565b6102c96104853660046133b5565b61113e565b6102566104983660046132aa565b611182565b6102a86104ab3660046132c5565b60086020525f908152604090205481565b6001546001600160a01b031661038f565b6102a86104db3660046132c5565b5f9081526008602052604090205490565b6102566104fa36600461343e565b6111d3565b6102c961050d3660046132c5565b611330565b5f5461038f906001600160a01b031681565b6102566105323660046132aa565b61160a565b610256610545366004613468565b611682565b6102a86105583660046132c5565b611845565b6102a8611876565b61056d601481565b60405160ff909116815260200161028c565b61025661058d3660046134cc565b611888565b6102566105a03660046132aa565b611b7a565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed3660046132c5565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a860025481565b61066261105d565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b18161108b565b81906106da576040516381e5828960e01b81526004016106d19190613418565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611bb4565b6001600160a01b0382165f908152600660205260408120805460ff191690556002805491610735836135e6565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611e56565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b03811115610820576108206135fb565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b03811115610864576108646135fb565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b161360f565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613623565b03610980578088848151811061090f5761090f61360f565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109675761096761360f565b60209081029190910101528261097c81613637565b9350505b50600101610893565b5050505050915091565b5f818152600a6020526040812081815460ff1660038111156109b7576109b7613623565b036109d557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a0a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a2e57610a2e613623565b14610a4c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a93573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab7919061364f565b905080610aca6040860160208701613679565b63ffffffff161115610ae26040860160208701613679565b829091610b10576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610b379042613692565b6003830155610b4b600583018560026131e1565b50610b54611876565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ba5928a928a92916136a5565b60405180910390a250600195945050505050565b5f610bc38261108b565b610bce57505f919050565b6001546001600160a01b0316610bf7576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c27908590600401613418565b602060405180830381865afa158015610c42573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c669190613704565b92915050565b5f818152600a602052604081206001815460ff166003811115610c9157610c91613623565b14610c9e57505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610ce757610ce7613623565b149392505050565b610cf7611e56565b6001600160a01b038116610d1e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610d6d611e56565b610d765f611e88565b565b600b545f9081906001600160a01b03163314610da75760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610dcc57610dcc613623565b14610dea57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610e2a57610e2a613623565b14610e3a57600a01549150610f17565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610e6e836135e6565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610ebf929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f2761105d565b6001600160a01b0316336001600160a01b03161480610f5057506001546001600160a01b031633145b610f6d57604051632864c4e160e01b815260040160405180910390fd5b610f768161108b565b61105a5760048054600160281b900464ffffffffff1690610fa0906001600160a01b038416611ef8565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610ff183613637565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906110db576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561113157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611113575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561117957611179613623565b14159392505050565b61118a611e56565b6001600160a01b0381166111b15760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6111dc6120ce565b805490915060ff600160401b82041615906001600160401b03165f811580156112025750825b90505f826001600160401b0316600114801561121d5750303b155b90508115801561122b575080155b156112495760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561127357845460ff60401b1916600160401b1785555b6001600160a01b03871661129a5760405163d92e233d60e01b815260040160405180910390fd5b6112a3336120f6565b6112af60046014612107565b6112b8866107a6565b6112c061105d565b6001600160a01b0316876001600160a01b0316146112e1576112e187611b7a565b831561132757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561135457611354613623565b0361137257604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561138a5761138a613623565b146113a857604051631860f69960e31b815260040160405180910390fd5b806003015442116113cc57604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806114b1578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b038111156114e1576114e16135fb565b60405190808252806020026020018201604052801561150a578160200160208202803683370190505b5090505f5b8281101561157c57846008015f8660060183815481106115315761153161360f565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106115695761156961360f565b602090810291909101015260010161150f565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b1580156115bf575f5ffd5b505af11580156115d1573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ba592919061371d565b611612611e56565b6001600160a01b0381166116395760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156116a6576116a6613623565b036116c457604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116dc576116dc613623565b146116fa57604051631860f69960e31b815260040160405180910390fd5b806003015442111561171f57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156117515760405163257309f160e11b815260040160405180910390fd5b61175a33610bb9565b6117775760405163149fbcfd60e11b815260040160405180910390fd5b611782338385612186565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff1916600117905590915061180190839083612357565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611871576040516322e679e360e11b815260040160405180910390fd5b919050565b5f61188360046014612558565b905090565b5f898152600a602052604090206002815460ff1660038111156118ad576118ad613623565b146118cb57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156118ee5760405163632a22bb60e01b815260040160405180910390fd5b600681015488146119375760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b5f61194485870187613874565b9150505f81511161198e5760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106d1565b5f816001835161199e9190613917565b815181106119ae576119ae61360f565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016119fa91815260200190565b5f60405180830381865afa158015611a14573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611a3b9190810190613a0c565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611a75908b908b908b908b90600401613b92565b602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061364f565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015611b13575f5ffd5b505af1158015611b25573d5f5f3e3d5ffd5b505050508c7f49ac1dd411942113d1c5e6799c6379ce341afe85a4175fb562cf2a5fb886c27d8d8d8d8d8d8d604051611b6396959493929190613bc3565b60405180910390a250505050505050505050505050565b611b82611e56565b6001600160a01b038116611bab575f604051631e4fbdf760e01b81526004016106d19190613418565b61105a81611e88565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611bf35760405162461bcd60e51b81526004016106d190613c3c565b825464ffffffffff600160281b90910481169082168111611c515760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611c648488612651565b64ffffffffff1681526020019081526020015f20819055505f816001611c8a9190613c86565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611cbf5750611e4e565b600185165f03611d86575f611cde83611cd9886001613c9f565b612651565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d3f91600401613cbc565b602060405180830381865af4158015611d5a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d7e919061364f565b935050611e3a565b5f611d9683611cd9600189613cec565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611df791600401613cbc565b602060405180830381865af4158015611e12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e36919061364f565b9350505b50647fffffffff600194851c169301611c54565b505050505050565b33611e5f61105d565b6001600160a01b031614610d76573360405163118cdaa760e01b81526004016106d19190613418565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611f475760405162461bcd60e51b81526004016106d190613c3c565b825464ffffffffff90811690821610611f9a5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611fa5816001613c9f565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611fdc8487612651565b64ffffffffff16815260208101919091526040015f205560018316156120c7575f61200c82611cd9600187613cec565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe9161206d91600401613cbc565b602060405180830381865af4158015612088573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120ac919061364f565b647fffffffff600195861c1694909350919091019050611fcc565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c66565b6120fe61266e565b61105a81612693565b602060ff821611156121555760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b612166600160ff831681901b613917565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121a65760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166121cf576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161220591613917565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561224c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612270919061364f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e7919061364f565b90505f81116123095760405163aeaddff160e01b815260040160405180910390fd5b5f6123148284613d09565b90505f81116123365760405163149fbcfd60e11b815260040160405180910390fd5b808611156113275760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156123d557508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612551565b5f5f90505f876008015f855f815481106123f1576123f161360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612479575f896008015f87848154811061243b5761243b61360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612470578092508193505b5060010161241a565b5080861061248d575f945050505050612551565b5f886009015f8685815481106124a5576124a561360f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156124e2576124e2613623565b0217905550868483815481106124fa576124fa61360f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116125ab5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156125cf5760405162461bcd60e51b81526004016106d190613d28565b8254600160281b900464ffffffffff16806125ee60ff85166002613e79565b64ffffffffff16101561263e5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b61264984828561269b565b949350505050565b5f8161266460ff851663ffffffff613e92565b6125519190613c9f565b612676612763565b610d7657604051631afcd79f60e31b815260040160405180910390fd5b611b8261266e565b5f602060ff831611156126c05760405162461bcd60e51b81526004016106d190613d28565b8264ffffffffff165f036126de576126d78261277c565b9050612551565b5f6126ea836001613c86565b60ff166001600160401b03811115612704576127046135fb565b60405190808252806020026020018201604052801561272d578160200160208202803683370190505b50905061273c85858584612e16565b808360ff16815181106127515761275161360f565b60200260200101519150509392505050565b5f61276c6120ce565b54600160401b900460ff16919050565b5f8160ff165f0361278e57505f919050565b8160ff166001036127c057507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036127f257507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361282457507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361285657507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361288857507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036128ba57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036128ec57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361291e57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361295057507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361298257507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b036129b457507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036129e657507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a1857507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612a4a57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612a7c57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612aae57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612ae057507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b1257507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b4457507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612b7657507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612ba857507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612bda57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c0c57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c3e57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612c7057507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612ca257507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612cd457507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d0657507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d3857507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612d6a57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612d9c57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612dce57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e3a5760405162461bcd60e51b81526004016106d190613d28565b5f8364ffffffffff1611612e9e5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612eaa600185613cec565b9050600181165f03612efd57846001015f612ec55f84612651565b64ffffffffff1681526020019081526020015f2054825f81518110612eec57612eec61360f565b602002602001018181525050612f25565b612f065f61277c565b825f81518110612f1857612f1861360f565b6020026020010181815250505b5f5b8360ff168160ff161015611e4e57600182165f0361301d5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612f7957612f7961360f565b60200260200101518152602001612f8f8561277c565b8152506040518263ffffffff1660e01b8152600401612fae9190613cbc565b602060405180830381865af4158015612fc9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fed919061364f565b83612ff9836001613c86565b60ff168151811061300c5761300c61360f565b6020026020010181815250506131ce565b5f613029826001613c86565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156130cb575f876001015f61308085600161306f9190613c86565b60018864ffffffffff16901c612651565b64ffffffffff1681526020019081526020015f2054905080858460016130a69190613c86565b60ff16815181106130b9576130b961360f565b602002602001018181525050506131cc565b5f876001015f6130e285600188611cd99190613cec565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff16815181106131395761313961360f565b60200260200101518152506040518263ffffffff1660e01b81526004016131609190613cbc565b602060405180830381865af415801561317b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061319f919061364f565b856131ab856001613c86565b60ff16815181106131be576131be61360f565b602002602001018181525050505b505b647fffffffff600192831c169101612f27565b600183019183908215613272579160200282015f5b8382111561324057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026131f6565b80156132705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613240565b505b5061327e929150613282565b5090565b5b8082111561327e575f8155600101613283565b6001600160a01b038116811461105a575f5ffd5b5f602082840312156132ba575f5ffd5b813561255181613296565b5f602082840312156132d5575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b828110156133155781516001600160a01b03168652602095860195909101906001016132ee565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613315578151865260209586019590910190600101613331565b604081525f61336160408301856132dc565b8281036020840152613373818561331f565b95945050505050565b5f5f5f6080848603121561338e575f5ffd5b8335925060208401359150608084018510156133a8575f5ffd5b6040840190509250925092565b5f5f604083850312156133c6575f5ffd5b8235915060208301356133d881613296565b809150509250929050565b5f5f5f606084860312156133f5575f5ffd5b83359250602084013561340781613296565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61255160208301846132dc565b5f5f6040838503121561344f575f5ffd5b823561345a81613296565b946020939093013593505050565b5f5f60408385031215613479575f5ffd5b50508035926020909101359150565b5f5f83601f840112613498575f5ffd5b5081356001600160401b038111156134ae575f5ffd5b6020830191508360208285010111156134c5575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c0312156134e4575f5ffd5b8935985060208a01356001600160401b03811115613500575f5ffd5b8a01601f81018c13613510575f5ffd5b80356001600160401b03811115613525575f5ffd5b8c60208260051b8401011115613539575f5ffd5b6020919091019850965060408a01356001600160401b0381111561355b575f5ffd5b6135678c828d01613488565b90975095505060608a01356001600160401b03811115613585575f5ffd5b6135918c828d01613488565b90955093505060808a01356001600160401b038111156135af575f5ffd5b6135bb8c828d01613488565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f816135f4576135f46135d2565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60018201613648576136486135d2565b5060010190565b5f6020828403121561365f575f5ffd5b5051919050565b803563ffffffff81168114611871575f5ffd5b5f60208284031215613689575f5ffd5b61255182613666565b80820180821115610c6657610c666135d2565b84815260a0810160208201855f5b60028110156136e05763ffffffff6136ca83613666565b16835260209283019291909101906001016136b3565b50505060608201939093526080015292915050565b80518015158114611871575f5ffd5b5f60208284031215613714575f5ffd5b612551826136f5565b604080825283549082018190525f8481526020812090916060840190835b818110156137625783546001600160a01b031683526001938401936020909301920161373b565b50508381036020850152613776818661331f565b9695505050505050565b6040516101e081016001600160401b03811182821017156137a3576137a36135fb565b60405290565b604051601f8201601f191681016001600160401b03811182821017156137d1576137d16135fb565b604052919050565b5f6001600160401b038211156137f1576137f16135fb565b50601f01601f191660200190565b5f82601f83011261380e575f5ffd5b81356001600160401b03811115613827576138276135fb565b8060051b613837602082016137a9565b91825260208185018101929081019086841115613852575f5ffd5b6020860192505b83831015613776578235825260209283019290910190613859565b5f5f60408385031215613885575f5ffd5b82356001600160401b0381111561389a575f5ffd5b8301601f810185136138aa575f5ffd5b80356138bd6138b8826137d9565b6137a9565b8181528660208385010111156138d1575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b03811115613901575f5ffd5b61390d858286016137ff565b9150509250929050565b81810381811115610c6657610c666135d2565b805160048110611871575f5ffd5b5f82601f830112613947575f5ffd5b604080519081016001600160401b0381118282101715613969576139696135fb565b806040525080604084018581111561397f575f5ffd5b845b81811015613999578051835260209283019201613981565b509195945050505050565b805161187181613296565b805160ff81168114611871575f5ffd5b5f82601f8301126139ce575f5ffd5b81516139dc6138b8826137d9565b8181528460208386010111156139f0575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613a1c575f5ffd5b81516001600160401b03811115613a31575f5ffd5b82016102008185031215613a43575f5ffd5b613a4b613780565b81518152613a5b6020830161392a565b602082015260408281015190820152613a778560608401613938565b606082015260a08201516080820152613a9260c083016139a4565b60a0820152613aa360e083016139af565b60c08201526101008201516001600160401b03811115613ac1575f5ffd5b613acd868285016139bf565b60e083015250613ae061012083016139a4565b610100820152613af361014083016139a4565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613b29575f5ffd5b613b35868285016139bf565b61018083015250613b496101c083016139a4565b6101a0820152613b5c6101e083016136f5565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613ba5604083018688613b6a565b8281036020840152613bb8818587613b6a565b979650505050505050565b606080825281018690525f8760808301825b89811015613c05578235613be881613296565b6001600160a01b0316825260209283019290910190600101613bd5565b508381036020850152613c1981888a613b6a565b9150508281036040840152613c2f818587613b6a565b9998505050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610c6657610c666135d2565b64ffffffffff8181168382160190811115610c6657610c666135d2565b6040810181835f5b6002811015613ce3578151835260209283019290910190600101613cc4565b50505092915050565b64ffffffffff8281168282160390811115610c6657610c666135d2565b5f82613d2357634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f1757808504811115613d8a57613d8a6135d2565b6001841615613d9857908102905b60019390931c928002613d6f565b5f82613db457506001610c66565b81613dc057505f610c66565b8160018114613dd65760028114613de057613e12565b6001915050610c66565b60ff841115613df157613df16135d2565b6001841b915064ffffffffff821115613e0c57613e0c6135d2565b50610c66565b5060208310610133831016604e8410600b8410161715613e4a575081810a64ffffffffff811115613e4557613e456135d2565b610c66565b613e5a64ffffffffff8484613d6b565b8064ffffffffff04821115613e7157613e716135d2565b029392505050565b5f61255164ffffffffff841664ffffffffff8416613da6565b64ffffffffff8181168382160290811690818114613eb257613eb26135d2565b509291505056fea164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e1461057f578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063e59e469514610524578063e6745e1314610537578063e82f3b701461054a578063ebf0c7171461055d578063f165053614610565575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104bc578063ca2869a0146104cd578063cd6dc687146104ec578063da881e5a146104ff578063dbb06c9314610512575f5ffd5b80639f0f874a1461044e578063a016493014610457578063a8a4d69b14610477578063bff232c11461048a578063c2b40ae41461049d575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103ce5780638da5cb5b146103e45780638e5ce3ad146103ec5780639015d371146103ff5780639a7a2ffc14610412575f5ffd5b8063715018a6146103475780637c92f5241461034f578063858142431461037c5780638a78bb151461039c5780638cb89ecb146103af575f5ffd5b80632e7b716d116102075780632e7b716d146102d95780634d6861a6146102ec57806350e6d94c146102ff5780635d5047761461032157806370e36bbe14610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610295578063291a691b146102b6575b5f5ffd5b6102566102513660046132aa565b61065a565b005b6102566102663660046132c5565b6107a6565b61027e6102793660046132c5565b6107e9565b60405161028c92919061334f565b60405180910390f35b6102a86102a33660046132c5565b610993565b60405190815260200161028c565b6102c96102c436600461337c565b6109df565b604051901515815260200161028c565b6102c96102e73660046132aa565b610bb9565b6102c96102fa3660046132c5565b610c6c565b6102c961030d3660046132aa565b60066020525f908152604090205460ff1681565b6102c961032f3660046133b5565b610cab565b6102566103423660046132aa565b610cef565b610256610d65565b61036261035d3660046133e3565b610d78565b6040805192835263ffffffff90911660208301520161028c565b60015461038f906001600160a01b031681565b60405161028c9190613418565b6102566103aa3660046132aa565b610f1f565b6102a86103bd3660046132c5565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a8565b61038f61105d565b600b5461038f906001600160a01b031681565b6102c961040d3660046132aa565b61108b565b6104386104203660046132aa565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102a860035481565b61046a6104653660046132c5565b6110a8565b60405161028c919061342c565b6102c96104853660046133b5565b61113e565b6102566104983660046132aa565b611182565b6102a86104ab3660046132c5565b60086020525f908152604090205481565b6001546001600160a01b031661038f565b6102a86104db3660046132c5565b5f9081526008602052604090205490565b6102566104fa36600461343e565b6111d3565b6102c961050d3660046132c5565b611330565b5f5461038f906001600160a01b031681565b6102566105323660046132aa565b61160a565b610256610545366004613468565b611682565b6102a86105583660046132c5565b611845565b6102a8611876565b61056d601481565b60405160ff909116815260200161028c565b61025661058d3660046134cc565b611888565b6102566105a03660046132aa565b611b7a565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed3660046132c5565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a860025481565b61066261105d565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b18161108b565b81906106da576040516381e5828960e01b81526004016106d19190613418565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611bb4565b6001600160a01b0382165f908152600660205260408120805460ff191690556002805491610735836135e6565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611e56565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b03811115610820576108206135fb565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b03811115610864576108646135fb565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b161360f565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613623565b03610980578088848151811061090f5761090f61360f565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109675761096761360f565b60209081029190910101528261097c81613637565b9350505b50600101610893565b5050505050915091565b5f818152600a6020526040812081815460ff1660038111156109b7576109b7613623565b036109d557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a0a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a2e57610a2e613623565b14610a4c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a93573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab7919061364f565b905080610aca6040860160208701613679565b63ffffffff161115610ae26040860160208701613679565b829091610b10576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610b379042613692565b6003830155610b4b600583018560026131e1565b50610b54611876565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ba5928a928a92916136a5565b60405180910390a250600195945050505050565b5f610bc38261108b565b610bce57505f919050565b6001546001600160a01b0316610bf7576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c27908590600401613418565b602060405180830381865afa158015610c42573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c669190613704565b92915050565b5f818152600a602052604081206001815460ff166003811115610c9157610c91613623565b14610c9e57505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610ce757610ce7613623565b149392505050565b610cf7611e56565b6001600160a01b038116610d1e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610d6d611e56565b610d765f611e88565b565b600b545f9081906001600160a01b03163314610da75760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610dcc57610dcc613623565b14610dea57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610e2a57610e2a613623565b14610e3a57600a01549150610f17565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610e6e836135e6565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610ebf929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f2761105d565b6001600160a01b0316336001600160a01b03161480610f5057506001546001600160a01b031633145b610f6d57604051632864c4e160e01b815260040160405180910390fd5b610f768161108b565b61105a5760048054600160281b900464ffffffffff1690610fa0906001600160a01b038416611ef8565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610ff183613637565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906110db576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561113157602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611113575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561117957611179613623565b14159392505050565b61118a611e56565b6001600160a01b0381166111b15760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6111dc6120ce565b805490915060ff600160401b82041615906001600160401b03165f811580156112025750825b90505f826001600160401b0316600114801561121d5750303b155b90508115801561122b575080155b156112495760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561127357845460ff60401b1916600160401b1785555b6001600160a01b03871661129a5760405163d92e233d60e01b815260040160405180910390fd5b6112a3336120f6565b6112af60046014612107565b6112b8866107a6565b6112c061105d565b6001600160a01b0316876001600160a01b0316146112e1576112e187611b7a565b831561132757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561135457611354613623565b0361137257604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561138a5761138a613623565b146113a857604051631860f69960e31b815260040160405180910390fd5b806003015442116113cc57604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806114b1578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b038111156114e1576114e16135fb565b60405190808252806020026020018201604052801561150a578160200160208202803683370190505b5090505f5b8281101561157c57846008015f8660060183815481106115315761153161360f565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106115695761156961360f565b602090810291909101015260010161150f565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b1580156115bf575f5ffd5b505af11580156115d1573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ba592919061371d565b611612611e56565b6001600160a01b0381166116395760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156116a6576116a6613623565b036116c457604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116dc576116dc613623565b146116fa57604051631860f69960e31b815260040160405180910390fd5b806003015442111561171f57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156117515760405163257309f160e11b815260040160405180910390fd5b61175a33610bb9565b6117775760405163149fbcfd60e11b815260040160405180910390fd5b611782338385612186565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff1916600117905590915061180190839083612357565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611871576040516322e679e360e11b815260040160405180910390fd5b919050565b5f61188360046014612558565b905090565b5f898152600a602052604090206002815460ff1660038111156118ad576118ad613623565b146118cb57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156118ee5760405163632a22bb60e01b815260040160405180910390fd5b600681015488146119375760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b5f61194485870187613874565b9150505f81511161198e5760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106d1565b5f816001835161199e9190613917565b815181106119ae576119ae61360f565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016119fa91815260200190565b5f60405180830381865afa158015611a14573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611a3b9190810190613a0c565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611a75908b908b908b908b90600401613b92565b602060405180830381865afa158015611a90573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061364f565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015611b13575f5ffd5b505af1158015611b25573d5f5f3e3d5ffd5b505050508c7f49ac1dd411942113d1c5e6799c6379ce341afe85a4175fb562cf2a5fb886c27d8d8d8d8d8d8d604051611b6396959493929190613bc3565b60405180910390a250505050505050505050505050565b611b82611e56565b6001600160a01b038116611bab575f604051631e4fbdf760e01b81526004016106d19190613418565b61105a81611e88565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611bf35760405162461bcd60e51b81526004016106d190613c3c565b825464ffffffffff600160281b90910481169082168111611c515760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611c648488612651565b64ffffffffff1681526020019081526020015f20819055505f816001611c8a9190613c86565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611cbf5750611e4e565b600185165f03611d86575f611cde83611cd9886001613c9f565b612651565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d3f91600401613cbc565b602060405180830381865af4158015611d5a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d7e919061364f565b935050611e3a565b5f611d9683611cd9600189613cec565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611df791600401613cbc565b602060405180830381865af4158015611e12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e36919061364f565b9350505b50647fffffffff600194851c169301611c54565b505050505050565b33611e5f61105d565b6001600160a01b031614610d76573360405163118cdaa760e01b81526004016106d19190613418565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611f475760405162461bcd60e51b81526004016106d190613c3c565b825464ffffffffff90811690821610611f9a5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611fa5816001613c9f565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611fdc8487612651565b64ffffffffff16815260208101919091526040015f205560018316156120c7575f61200c82611cd9600187613cec565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe9161206d91600401613cbc565b602060405180830381865af4158015612088573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120ac919061364f565b647fffffffff600195861c1694909350919091019050611fcc565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c66565b6120fe61266e565b61105a81612693565b602060ff821611156121555760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b612166600160ff831681901b613917565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121a65760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166121cf576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161220591613917565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561224c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612270919061364f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122e7919061364f565b90505f81116123095760405163aeaddff160e01b815260040160405180910390fd5b5f6123148284613d09565b90505f81116123365760405163149fbcfd60e11b815260040160405180910390fd5b808611156113275760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156123d557508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612551565b5f5f90505f876008015f855f815481106123f1576123f161360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612479575f896008015f87848154811061243b5761243b61360f565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612470578092508193505b5060010161241a565b5080861061248d575f945050505050612551565b5f886009015f8685815481106124a5576124a561360f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156124e2576124e2613623565b0217905550868483815481106124fa576124fa61360f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116125ab5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156125cf5760405162461bcd60e51b81526004016106d190613d28565b8254600160281b900464ffffffffff16806125ee60ff85166002613e79565b64ffffffffff16101561263e5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b61264984828561269b565b949350505050565b5f8161266460ff851663ffffffff613e92565b6125519190613c9f565b612676612763565b610d7657604051631afcd79f60e31b815260040160405180910390fd5b611b8261266e565b5f602060ff831611156126c05760405162461bcd60e51b81526004016106d190613d28565b8264ffffffffff165f036126de576126d78261277c565b9050612551565b5f6126ea836001613c86565b60ff166001600160401b03811115612704576127046135fb565b60405190808252806020026020018201604052801561272d578160200160208202803683370190505b50905061273c85858584612e16565b808360ff16815181106127515761275161360f565b60200260200101519150509392505050565b5f61276c6120ce565b54600160401b900460ff16919050565b5f8160ff165f0361278e57505f919050565b8160ff166001036127c057507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036127f257507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361282457507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361285657507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361288857507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036128ba57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036128ec57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361291e57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361295057507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361298257507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b036129b457507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036129e657507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a1857507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612a4a57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612a7c57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612aae57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612ae057507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b1257507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b4457507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612b7657507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612ba857507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612bda57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c0c57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c3e57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612c7057507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612ca257507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612cd457507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d0657507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d3857507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612d6a57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612d9c57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612dce57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e3a5760405162461bcd60e51b81526004016106d190613d28565b5f8364ffffffffff1611612e9e5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612eaa600185613cec565b9050600181165f03612efd57846001015f612ec55f84612651565b64ffffffffff1681526020019081526020015f2054825f81518110612eec57612eec61360f565b602002602001018181525050612f25565b612f065f61277c565b825f81518110612f1857612f1861360f565b6020026020010181815250505b5f5b8360ff168160ff161015611e4e57600182165f0361301d5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612f7957612f7961360f565b60200260200101518152602001612f8f8561277c565b8152506040518263ffffffff1660e01b8152600401612fae9190613cbc565b602060405180830381865af4158015612fc9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fed919061364f565b83612ff9836001613c86565b60ff168151811061300c5761300c61360f565b6020026020010181815250506131ce565b5f613029826001613c86565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156130cb575f876001015f61308085600161306f9190613c86565b60018864ffffffffff16901c612651565b64ffffffffff1681526020019081526020015f2054905080858460016130a69190613c86565b60ff16815181106130b9576130b961360f565b602002602001018181525050506131cc565b5f876001015f6130e285600188611cd99190613cec565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff16815181106131395761313961360f565b60200260200101518152506040518263ffffffff1660e01b81526004016131609190613cbc565b602060405180830381865af415801561317b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061319f919061364f565b856131ab856001613c86565b60ff16815181106131be576131be61360f565b602002602001018181525050505b505b647fffffffff600192831c169101612f27565b600183019183908215613272579160200282015f5b8382111561324057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026131f6565b80156132705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613240565b505b5061327e929150613282565b5090565b5b8082111561327e575f8155600101613283565b6001600160a01b038116811461105a575f5ffd5b5f602082840312156132ba575f5ffd5b813561255181613296565b5f602082840312156132d5575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b828110156133155781516001600160a01b03168652602095860195909101906001016132ee565b5093949350505050565b5f8151808452602084019350602083015f5b82811015613315578151865260209586019590910190600101613331565b604081525f61336160408301856132dc565b8281036020840152613373818561331f565b95945050505050565b5f5f5f6080848603121561338e575f5ffd5b8335925060208401359150608084018510156133a8575f5ffd5b6040840190509250925092565b5f5f604083850312156133c6575f5ffd5b8235915060208301356133d881613296565b809150509250929050565b5f5f5f606084860312156133f5575f5ffd5b83359250602084013561340781613296565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61255160208301846132dc565b5f5f6040838503121561344f575f5ffd5b823561345a81613296565b946020939093013593505050565b5f5f60408385031215613479575f5ffd5b50508035926020909101359150565b5f5f83601f840112613498575f5ffd5b5081356001600160401b038111156134ae575f5ffd5b6020830191508360208285010111156134c5575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c0312156134e4575f5ffd5b8935985060208a01356001600160401b03811115613500575f5ffd5b8a01601f81018c13613510575f5ffd5b80356001600160401b03811115613525575f5ffd5b8c60208260051b8401011115613539575f5ffd5b6020919091019850965060408a01356001600160401b0381111561355b575f5ffd5b6135678c828d01613488565b90975095505060608a01356001600160401b03811115613585575f5ffd5b6135918c828d01613488565b90955093505060808a01356001600160401b038111156135af575f5ffd5b6135bb8c828d01613488565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f816135f4576135f46135d2565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60018201613648576136486135d2565b5060010190565b5f6020828403121561365f575f5ffd5b5051919050565b803563ffffffff81168114611871575f5ffd5b5f60208284031215613689575f5ffd5b61255182613666565b80820180821115610c6657610c666135d2565b84815260a0810160208201855f5b60028110156136e05763ffffffff6136ca83613666565b16835260209283019291909101906001016136b3565b50505060608201939093526080015292915050565b80518015158114611871575f5ffd5b5f60208284031215613714575f5ffd5b612551826136f5565b604080825283549082018190525f8481526020812090916060840190835b818110156137625783546001600160a01b031683526001938401936020909301920161373b565b50508381036020850152613776818661331f565b9695505050505050565b6040516101e081016001600160401b03811182821017156137a3576137a36135fb565b60405290565b604051601f8201601f191681016001600160401b03811182821017156137d1576137d16135fb565b604052919050565b5f6001600160401b038211156137f1576137f16135fb565b50601f01601f191660200190565b5f82601f83011261380e575f5ffd5b81356001600160401b03811115613827576138276135fb565b8060051b613837602082016137a9565b91825260208185018101929081019086841115613852575f5ffd5b6020860192505b83831015613776578235825260209283019290910190613859565b5f5f60408385031215613885575f5ffd5b82356001600160401b0381111561389a575f5ffd5b8301601f810185136138aa575f5ffd5b80356138bd6138b8826137d9565b6137a9565b8181528660208385010111156138d1575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b03811115613901575f5ffd5b61390d858286016137ff565b9150509250929050565b81810381811115610c6657610c666135d2565b805160048110611871575f5ffd5b5f82601f830112613947575f5ffd5b604080519081016001600160401b0381118282101715613969576139696135fb565b806040525080604084018581111561397f575f5ffd5b845b81811015613999578051835260209283019201613981565b509195945050505050565b805161187181613296565b805160ff81168114611871575f5ffd5b5f82601f8301126139ce575f5ffd5b81516139dc6138b8826137d9565b8181528460208386010111156139f0575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613a1c575f5ffd5b81516001600160401b03811115613a31575f5ffd5b82016102008185031215613a43575f5ffd5b613a4b613780565b81518152613a5b6020830161392a565b602082015260408281015190820152613a778560608401613938565b606082015260a08201516080820152613a9260c083016139a4565b60a0820152613aa360e083016139af565b60c08201526101008201516001600160401b03811115613ac1575f5ffd5b613acd868285016139bf565b60e083015250613ae061012083016139a4565b610100820152613af361014083016139a4565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613b29575f5ffd5b613b35868285016139bf565b61018083015250613b496101c083016139a4565b6101a0820152613b5c6101e083016136f5565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613ba5604083018688613b6a565b8281036020840152613bb8818587613b6a565b979650505050505050565b606080825281018690525f8760808301825b89811015613c05578235613be881613296565b6001600160a01b0316825260209283019290910190600101613bd5565b508381036020850152613c1981888a613b6a565b9150508281036040840152613c2f818587613b6a565b9998505050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610c6657610c666135d2565b64ffffffffff8181168382160190811115610c6657610c666135d2565b6040810181835f5b6002811015613ce3578151835260209283019290910190600101613cc4565b50505092915050565b64ffffffffff8281168282160390811115610c6657610c666135d2565b5f82613d2357634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f1757808504811115613d8a57613d8a6135d2565b6001841615613d9857908102905b60019390931c928002613d6f565b5f82613db457506001610c66565b81613dc057505f610c66565b8160018114613dd65760028114613de057613e12565b6001915050610c66565b60ff841115613df157613df16135d2565b6001841b915064ffffffffff821115613e0c57613e0c6135d2565b50610c66565b5060208310610133831016604e8410600b8410161715613e4a575081810a64ffffffffff811115613e4557613e456135d2565b610c66565b613e5a64ffffffffff8484613d6b565b8064ffffffffff04821115613e7157613e716135d2565b029392505050565b5f61255164ffffffffff841664ffffffffff8416613da6565b64ffffffffff8181168382160290811690818114613eb257613eb26135d2565b509291505056fea164736f6c634300081c000a", "linkReferences": { "npm/poseidon-solidity@0.0.5/PoseidonT3.sol": { "PoseidonT3": [ @@ -1320,5 +1320,5 @@ }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-67d7bf420ed8ac25001394841682e83cf4523ea2" + "buildInfoId": "solc-0_8_28-a5591f76a7a8353e3d0dd83e83c16479678f73a9" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index f0edca06fd..42cd3c06aa 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -81,9 +81,10 @@ contract Enclave is IEnclave, OwnableUpgradeable { mapping(bytes32 encryptionSchemeId => IPkVerifier pkVerifier) public pkVerifiers; - /// @notice Mapping storing valid E3 program ABI encoded parameter sets. - /// @dev Stores allowed encryption scheme parameters (e.g., BFV parameters). - mapping(bytes e3ProgramParams => bool allowed) public e3ProgramsParams; + /// @notice Mapping from param set index to ABI-encoded BFV parameters. + /// @dev Ciphernodes map the uint8 index to their local BfvPreset. + /// New param sets can be added without a contract upgrade. + mapping(uint8 => bytes) public paramSetRegistry; /// @notice Mapping tracking fee payments for each E3. /// @dev Stores the amount paid for an E3, distributed to committee upon completion. @@ -174,7 +175,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { /// @param _feeToken The address of the ERC20 token used for E3 fees. /// @param _maxDuration The maximum duration of a computation in seconds. /// @param config Initial timeout configuration for E3 lifecycle stages. - /// @param _e3ProgramsParams Array of ABI encoded E3 encryption scheme parameters sets (e.g., for BFV). function initialize( address _owner, ICiphernodeRegistry _ciphernodeRegistry, @@ -182,8 +182,7 @@ contract Enclave is IEnclave, OwnableUpgradeable { IE3RefundManager _e3RefundManager, IERC20 _feeToken, uint256 _maxDuration, - E3TimeoutConfig calldata config, - bytes[] memory _e3ProgramsParams + E3TimeoutConfig calldata config ) public initializer { __Ownable_init(msg.sender); setMaxDuration(_maxDuration); @@ -192,7 +191,6 @@ contract Enclave is IEnclave, OwnableUpgradeable { setE3RefundManager(_e3RefundManager); setFeeToken(_feeToken); _setTimeoutConfig(config); - setE3ProgramsParams(_e3ProgramsParams); // Set default pricing parameters _pricingConfig = PricingConfig({ @@ -284,7 +282,7 @@ contract Enclave is IEnclave, OwnableUpgradeable { e3.requestBlock = block.number; e3.inputWindow = requestParams.inputWindow; e3.e3Program = requestParams.e3Program; - e3.e3ProgramParams = requestParams.e3ProgramParams; + e3.paramSet = requestParams.paramSet; e3.customParams = requestParams.customParams; e3.proofAggregationEnabled = requestParams.proofAggregationEnabled; e3.committeePublicKey = hex""; @@ -294,10 +292,13 @@ contract Enclave is IEnclave, OwnableUpgradeable { feeToken.safeTransferFrom(msg.sender, address(this), e3Fee); + bytes memory e3ProgramParams = paramSetRegistry[requestParams.paramSet]; + require(e3ProgramParams.length > 0, "BFV param set not registered"); + bytes32 encryptionSchemeId = requestParams.e3Program.validate( e3Id, seed, - requestParams.e3ProgramParams, + e3ProgramParams, requestParams.computeProviderParams, requestParams.customParams ); @@ -651,27 +652,17 @@ contract Enclave is IEnclave, OwnableUpgradeable { emit EncryptionSchemeDisabled(encryptionSchemeId); } - /// @inheritdoc IEnclave - function setE3ProgramsParams( - bytes[] memory _e3ProgramsParams - ) public onlyOwner { - uint256 length = _e3ProgramsParams.length; - for (uint256 i; i < length; ++i) { - e3ProgramsParams[_e3ProgramsParams[i]] = true; - } - emit AllowedE3ProgramsParamsSet(_e3ProgramsParams); - } - - /// @notice Removes previously allowed E3 program parameter sets - /// @param _e3ProgramsParams Array of ABI encoded parameter sets to remove - function removeE3ProgramsParams( - bytes[] memory _e3ProgramsParams + /// @notice Registers ABI-encoded BFV parameters for a param set index. + /// @param paramSet The param set index (0 = Insecure512, 1 = Secure8192, ...). + /// @param encodedParams ABI-encoded BFV parameters (degree, plaintext_modulus, moduli[]). + function setParamSet( + uint8 paramSet, + bytes calldata encodedParams ) public onlyOwner { - uint256 length = _e3ProgramsParams.length; - for (uint256 i; i < length; ++i) { - delete e3ProgramsParams[_e3ProgramsParams[i]]; - } - emit E3ProgramsParamsRemoved(_e3ProgramsParams); + require(encodedParams.length > 0, "Empty params"); + require(paramSetRegistry[paramSet].length == 0, "ParamSet already registered"); + paramSetRegistry[paramSet] = encodedParams; + emit ParamSetRegistered(paramSet, encodedParams); } /// @notice Sets the E3 Refund Manager contract address @@ -1028,6 +1019,10 @@ contract Enclave is IEnclave, OwnableUpgradeable { function getE3Quote( E3RequestParams calldata requestParams ) public view returns (uint256 fee) { + require( + paramSetRegistry[requestParams.paramSet].length > 0, + "BFV param set not registered" + ); uint32[2] memory threshold = committeeThresholds[ requestParams.committeeSize ]; diff --git a/packages/enclave-contracts/contracts/interfaces/IE3.sol b/packages/enclave-contracts/contracts/interfaces/IE3.sol index 84510ac8ff..a821787f39 100644 --- a/packages/enclave-contracts/contracts/interfaces/IE3.sol +++ b/packages/enclave-contracts/contracts/interfaces/IE3.sol @@ -21,7 +21,7 @@ import { IEnclave } from "./IEnclave.sol"; * @param inputWindow When to start and stop accepting inputs from data providers * @param encryptionSchemeId Identifier for the encryption scheme used in this computation * @param e3Program Address of the E3 Program contract that validates and verifies the computation - * @param e3ProgramParams ABI encoded computation parameters specific to the E3 program + * @param paramSet BFV encryption parameter set used for this computation * @param customParams Arbitrary ABI-encoded application-defined parameters. * @param decryptionVerifier Address of the output verifier contract for decryption verification * @param committeePublicKey Hash of the public key of the selected committee for this computation @@ -36,7 +36,7 @@ struct E3 { uint256[2] inputWindow; bytes32 encryptionSchemeId; IE3Program e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes customParams; IDecryptionVerifier decryptionVerifier; IPkVerifier pkVerifier; diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index 0c64edf242..cb6c1dd58d 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -27,6 +27,10 @@ interface IEnclave { Large } + /// @notice BFV encryption parameter sets. + /// @dev Each variant maps to a threshold BFV preset. The DKG counterpart is + /// derived automatically via `BfvPreset::dkg_counterpart()` on the node side. + /// @notice Lifecycle stages of an E3 computation enum E3Stage { None, @@ -181,13 +185,10 @@ interface IEnclave { /// @param e3Program The address of the E3 Program. event E3ProgramDisabled(IE3Program e3Program); - /// @notice Emitted when the allowed E3 encryption scheme parameters are configured. - /// @param e3ProgramParams Array of encoded encryption scheme parameters (e.g, for BFV) - event AllowedE3ProgramsParamsSet(bytes[] e3ProgramParams); - - /// @notice Emitted when E3 program parameter sets are removed. - /// @param e3ProgramParams Array of removed encryption scheme parameters. - event E3ProgramsParamsRemoved(bytes[] e3ProgramParams); + /// @notice Emitted when a BFV param set is registered or updated. + /// @param paramSet The param set index. + /// @param encodedParams ABI-encoded BFV parameters. + event ParamSetRegistered(uint8 paramSet, bytes encodedParams); /// @notice Emitted when E3RefundManager contract is set. /// @param e3RefundManager The address of the E3RefundManager contract. @@ -411,14 +412,14 @@ interface IEnclave { /// @param committeeSize The M/N threshold and honest parties for the committee. /// @param inputWindow When the program will start and stop accepting inputs. /// @param e3Program The address of the E3 Program. - /// @param e3ProgramParams The ABI encoded computation parameters. + /// @param paramSet The BFV encryption parameter set to use. /// @param computeProviderParams The ABI encoded compute provider parameters. /// @param customParams Arbitrary ABI-encoded application-defined parameters. struct E3RequestParams { CommitteeSize committeeSize; uint256[2] inputWindow; IE3Program e3Program; - bytes e3ProgramParams; + uint8 paramSet; bytes computeProviderParams; bytes customParams; /// @notice When true, ciphernodes generate and fold wrapper proofs @@ -527,15 +528,10 @@ interface IEnclave { /// @param encryptionSchemeId The unique identifier for the encryption scheme to disable. function disableEncryptionScheme(bytes32 encryptionSchemeId) external; - /// @notice Sets the allowed E3 program parameters. - /// @dev This function enables specific parameter sets for E3 programs (e.g., BFV encryption parameters). - /// @param _e3ProgramsParams Array of ABI encoded parameter sets to allow. - function setE3ProgramsParams(bytes[] memory _e3ProgramsParams) external; - - /// @notice Removes previously allowed E3 program parameter sets. - /// @dev This function revokes specific parameter sets that should no longer be allowed. - /// @param _e3ProgramsParams Array of ABI encoded parameter sets to remove. - function removeE3ProgramsParams(bytes[] memory _e3ProgramsParams) external; + /// @notice Registers ABI-encoded BFV parameters for a param set enum variant. + /// @param paramSet The param set index to register. + /// @param encodedParams ABI-encoded BFV parameters. + function setParamSet(uint8 paramSet, bytes calldata encodedParams) external; /// @notice Sets the full pricing configuration. /// @param config The new pricing configuration. diff --git a/packages/enclave-contracts/deployed_contracts.json b/packages/enclave-contracts/deployed_contracts.json index 358966c089..594f486eb9 100644 --- a/packages/enclave-contracts/deployed_contracts.json +++ b/packages/enclave-contracts/deployed_contracts.json @@ -151,21 +151,21 @@ }, "localhost": { "PoseidonT3": { - "blockNumber": 6, + "blockNumber": 1, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 7, + "blockNumber": 2, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 8, + "blockNumber": 3, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { @@ -174,14 +174,14 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 10, + "blockNumber": 5, "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 11, + "blockNumber": 6, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "CiphernodeRegistryOwnable": { @@ -196,7 +196,7 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 12, + "blockNumber": 7, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "BondingRegistry": { @@ -218,7 +218,7 @@ "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 13, + "blockNumber": 8, "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { @@ -229,19 +229,16 @@ "e3RefundManager": "0x0000000000000000000000000000000000000001", "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "maxDuration": "2592000", - "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}", - "params": [ - "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000" - ] + "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" }, "proxyRecords": { - "initData": "0x01d12f1c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000", + "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 16, + "blockNumber": 11, "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "E3RefundManager": { @@ -257,24 +254,24 @@ "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, - "blockNumber": 18, + "blockNumber": 13, "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, "MockComputeProvider": { - "blockNumber": 20, - "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" + "blockNumber": 33, + "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" }, "MockDecryptionVerifier": { - "blockNumber": 21, - "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" + "blockNumber": 34, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" }, "MockPkVerifier": { - "blockNumber": 22, - "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + "blockNumber": 35, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" }, "MockE3Program": { - "blockNumber": 23, - "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" + "blockNumber": 36, + "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" } } } \ No newline at end of file diff --git a/packages/enclave-contracts/ignition/modules/enclave.ts b/packages/enclave-contracts/ignition/modules/enclave.ts index e6990e143f..86d362fa03 100644 --- a/packages/enclave-contracts/ignition/modules/enclave.ts +++ b/packages/enclave-contracts/ignition/modules/enclave.ts @@ -6,7 +6,6 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; export default buildModule("Enclave", (m) => { - const params = m.getParameter("params"); const owner = m.getParameter("owner"); const maxDuration = m.getParameter("maxDuration"); const registry = m.getParameter("registry"); @@ -30,7 +29,6 @@ export default buildModule("Enclave", (m) => { feeToken, maxDuration, timeoutConfig, - [params], ]); const enclave = m.contract("TransparentUpgradeableProxy", [ diff --git a/packages/enclave-contracts/scripts/deployAndSave/enclave.ts b/packages/enclave-contracts/scripts/deployAndSave/enclave.ts index b8aa4f0dfd..173b9a77f7 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/enclave.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/enclave.ts @@ -7,11 +7,7 @@ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { Enclave, Enclave__factory as EnclaveFactory } from "../../types"; import { getProxyAdmin, verifyProxyAdminOwner } from "../proxy"; -import { - areArraysEqual, - readDeploymentArgs, - storeDeploymentArgs, -} from "../utils"; +import { readDeploymentArgs, storeDeploymentArgs } from "../utils"; /** * Timeout configuration for E3 stages @@ -27,7 +23,6 @@ export interface E3TimeoutConfig { * The arguments for the deployAndSaveEnclave function */ export interface EnclaveArgs { - params?: string[]; owner?: string; maxDuration?: string; registry?: string; @@ -44,7 +39,6 @@ export interface EnclaveArgs { * @returns The deployed Enclave contract */ export const deployAndSaveEnclave = async ({ - params, owner, maxDuration, registry, @@ -62,7 +56,6 @@ export const deployAndSaveEnclave = async ({ const preDeployedArgs = readDeploymentArgs("Enclave", chain); if ( - !params || !owner || !maxDuration || !registry || @@ -76,10 +69,7 @@ export const deployAndSaveEnclave = async ({ preDeployedArgs?.constructorArgs?.bondingRegistry === bondingRegistry && preDeployedArgs?.constructorArgs?.e3RefundManager === e3RefundManager && preDeployedArgs?.constructorArgs?.feeToken === feeToken && - areArraysEqual( - preDeployedArgs?.constructorArgs?.params as string[], - params, - )) + true) ) { if (!preDeployedArgs?.address) { throw new Error("Enclave address not found, it must be deployed first"); @@ -106,7 +96,6 @@ export const deployAndSaveEnclave = async ({ feeToken, maxDuration, timeoutConfig, - params, ]); const ProxyCF = await ethers.getContractFactory( @@ -128,7 +117,6 @@ export const deployAndSaveEnclave = async ({ feeToken, maxDuration, timeoutConfig: JSON.stringify(timeoutConfig), - params, }, proxyRecords: { initData, diff --git a/packages/enclave-contracts/scripts/deployEnclave.ts b/packages/enclave-contracts/scripts/deployEnclave.ts index c0051a6486..a37768e3ae 100644 --- a/packages/enclave-contracts/scripts/deployEnclave.ts +++ b/packages/enclave-contracts/scripts/deployEnclave.ts @@ -146,7 +146,6 @@ export const deployEnclave = async ( console.log("Deploying Enclave..."); const { enclave } = await deployAndSaveEnclave({ - params: [encoded], owner: ownerAddress, maxDuration: THIRTY_DAYS_IN_SECONDS.toString(), registry: ciphernodeRegistryAddress, @@ -231,6 +230,11 @@ export const deployEnclave = async ( // Medium and Large can be set later as needed console.log("Committee thresholds set (Micro=[1,3], Small=[2,5])"); + // Register BFV param sets + console.log("Registering BFV param sets..."); + await enclave.setParamSet(0, encoded); // ParamSet.Insecure512 + console.log("ParamSet.Insecure512 registered"); + const encryptionSchemeId = ethers.keccak256(ethers.toUtf8Bytes("fhe.rs:BFV")); // Set pricing config with protocol treasury diff --git a/packages/enclave-contracts/tasks/enclave.ts b/packages/enclave-contracts/tasks/enclave.ts index 3e234e5b2a..1ae4d1ec1e 100644 --- a/packages/enclave-contracts/tasks/enclave.ts +++ b/packages/enclave-contracts/tasks/enclave.ts @@ -192,10 +192,8 @@ export const requestCommittee = task( hre.globalOptions.network, ); - let e3ProgramParams = e3Params; - if (e3ProgramParams === ZeroAddress) { - e3ProgramParams = zeroPadValue(e3ProgramParams, 32); - } + // paramSet: 0 = Insecure512, 1 = Secure8192 + const paramSet = 0; let computeProviderParams = computeParams; const mockDecryptionVerifierArgs = readDeploymentArgs( @@ -227,7 +225,7 @@ export const requestCommittee = task( ], e3Program: e3Address === ZeroAddress ? mockE3ProgramArgs!.address : e3Address, - e3ProgramParams, + paramSet, computeProviderParams, customParams, proofAggregationEnabled, diff --git a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts index d8eac31daa..ebba4c6992 100644 --- a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -178,7 +178,6 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: ownerAddress, maxDuration: THIRTY_DAYS, registry: ciphernodeRegistryAddress, @@ -247,6 +246,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await enclave.setE3RefundManager(e3RefundManagerAddress); await enclave.setSlashingManager(await slashingManager.getAddress()); await enclave.enableE3Program(await e3Program.getAddress()); + await enclave.setParamSet(0, encodedE3ProgramParams); await enclave.setDecryptionVerifier( encryptionSchemeId, await decryptionVerifier.getAddress(), @@ -305,7 +305,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { committeeSize, inputWindow: [startTime + 100, startTime + ONE_DAY] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], @@ -521,7 +521,6 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const newEnclaveContract = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: await owner.getAddress(), maxDuration: THIRTY_DAYS, registry: await enclave.ciphernodeRegistry(), @@ -1268,7 +1267,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { committeeSize: 0, inputWindow: [startTime, startTime + ONE_DAY] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], @@ -1351,7 +1350,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { committeeSize: 0, inputWindow: [startTime, startTime + ONE_DAY] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], diff --git a/packages/enclave-contracts/test/Enclave.spec.ts b/packages/enclave-contracts/test/Enclave.spec.ts index ce9d2af7be..6885751758 100644 --- a/packages/enclave-contracts/test/Enclave.spec.ts +++ b/packages/enclave-contracts/test/Enclave.spec.ts @@ -188,7 +188,6 @@ describe("Enclave", function () { const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: ownerAddress, maxDuration: THIRTY_DAYS_IN_SECONDS, registry: ciphernodeRegistryAddress, @@ -243,7 +242,7 @@ describe("Enclave", function () { await ignition.deploy(MockE3ProgramModule); await enclave.enableE3Program(await e3Program.getAddress()); - await enclave.setE3ProgramsParams([encodedE3ProgramParams]); + await enclave.setParamSet(0, encodedE3ProgramParams); await enclave.setDecryptionVerifier( encryptionSchemeId, await decryptionVerifier.getAddress(), @@ -285,7 +284,7 @@ describe("Enclave", function () { committeeSize: 0, // Micro inputWindow: [now + 10, now + inputWindowDuration] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], @@ -406,48 +405,35 @@ describe("Enclave", function () { }); }); - describe("setE3ProgramsParams()", function () { - const encodedE3ProgramsParams = [encodedE3ProgramParams]; - + describe("setParamSet()", function () { it("reverts if not called by owner", async function () { const { enclave, notTheOwner } = await loadFixture(setup); await expect( - enclave - .connect(notTheOwner) - .setE3ProgramsParams(encodedE3ProgramsParams), + enclave.connect(notTheOwner).setParamSet(0, encodedE3ProgramParams), ) .to.be.revertedWithCustomError(enclave, "OwnableUnauthorizedAccount") .withArgs(notTheOwner); }); - it("sets E3 program parameters correctly", async function () { + it("registers param set and emits event", async function () { const { enclave } = await loadFixture(setup); - await enclave.setE3ProgramsParams(encodedE3ProgramsParams); - expect(await enclave.e3ProgramsParams(encodedE3ProgramsParams[0]!)).to.be - .true; - }); - - it("emits AllowedE3ProgramsParamsSet event", async function () { - const { enclave } = await loadFixture(setup); + await expect(enclave.setParamSet(1, encodedE3ProgramParams)) + .to.emit(enclave, "ParamSetRegistered") + .withArgs(1, encodedE3ProgramParams); - await expect(enclave.setE3ProgramsParams(encodedE3ProgramsParams)) - .to.emit(enclave, "AllowedE3ProgramsParamsSet") - .withArgs(encodedE3ProgramsParams); + expect(await enclave.paramSetRegistry(1)).to.equal( + encodedE3ProgramParams, + ); }); - it("handles multiple parameters", async function () { + it("reverts with empty params", async function () { const { enclave } = await loadFixture(setup); - encodedE3ProgramsParams.push( - "0x0000000000000000000000000000000000000000000000000000000000000001", - ); - await enclave.setE3ProgramsParams(encodedE3ProgramsParams); - - for (const param of encodedE3ProgramsParams) { - expect(await enclave.e3ProgramsParams(param)).to.be.true; - } + await expect(enclave.setParamSet(0, "0x")).to.be.revertedWith( + "Empty params", + ); }); }); @@ -467,7 +453,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -479,7 +465,7 @@ describe("Enclave", function () { expect(e3.inputWindow[0]).to.equal(request.inputWindow[0]); expect(e3.inputWindow[1]).to.equal(request.inputWindow[1]); expect(e3.e3Program).to.equal(request.e3Program); - expect(e3.e3ProgramParams).to.equal(request.e3ProgramParams); + expect(e3.paramSet).to.equal(request.paramSet); expect(e3.decryptionVerifier).to.equal( abiCoder.decode(["address"], request.computeProviderParams)[0], ); @@ -671,7 +657,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -686,7 +672,7 @@ describe("Enclave", function () { committeeSize: 3, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -706,7 +692,7 @@ describe("Enclave", function () { request.inputWindow[1] + time.duration.days(31), ], e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -721,7 +707,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: ethers.ZeroAddress, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -738,7 +724,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -754,7 +740,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -781,7 +767,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -819,7 +805,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: request.inputWindow, e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, @@ -894,7 +880,7 @@ describe("Enclave", function () { committeeSize: request.committeeSize, inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], e3Program: request.e3Program, - e3ProgramParams: request.e3ProgramParams, + paramSet: request.paramSet, computeProviderParams: request.computeProviderParams, customParams: request.customParams, proofAggregationEnabled: false, diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index c773286b65..9b4960a5c1 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -222,7 +222,6 @@ describe("E3 Pricing", function () { const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: ownerAddress, maxDuration: THIRTY_DAYS_IN_SECONDS, registry: ciphernodeRegistryAddress, @@ -273,7 +272,7 @@ describe("E3 Pricing", function () { await ignition.deploy(MockPkVerifierModule); await enclave.enableE3Program(await e3Program.getAddress()); - await enclave.setE3ProgramsParams([encodedE3ProgramParams]); + await enclave.setParamSet(0, encodedE3ProgramParams); await enclave.setDecryptionVerifier( encryptionSchemeId, await decryptionVerifier.getAddress(), @@ -312,7 +311,7 @@ describe("E3 Pricing", function () { committeeSize: 0, // Micro inputWindow: [now + 10, now + inputWindowDuration] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], @@ -595,7 +594,7 @@ describe("E3 Pricing", function () { number, ], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], @@ -678,7 +677,7 @@ describe("E3 Pricing", function () { number, ], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], diff --git a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts index 1af2dc7c51..02cc1a9843 100644 --- a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts +++ b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts @@ -141,7 +141,6 @@ describe("CiphernodeRegistryOwnable", function () { const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: ownerAddress, maxDuration: 60 * 60 * 24 * 30, // 30 days registry: registryAddress, @@ -194,7 +193,7 @@ describe("CiphernodeRegistryOwnable", function () { const { mockPkVerifier } = await ignition.deploy(MockPkVerifierModule); await enclave.enableE3Program(await mockE3Program.getAddress()); - await enclave.setE3ProgramsParams([encodedE3ProgramParams]); + await enclave.setParamSet(0, encodedE3ProgramParams); await enclave.setDecryptionVerifier( encryptionSchemeId, await mockDecryptionVerifier.getAddress(), @@ -266,7 +265,7 @@ describe("CiphernodeRegistryOwnable", function () { committeeSize: 0, inputWindow: [currentTime + 100, currentTime + 300] as [number, number], e3Program: await mockE3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await mockDecryptionVerifier.getAddress()], diff --git a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts index 00357d35bc..f799f6cd36 100644 --- a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts +++ b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts @@ -194,7 +194,6 @@ describe("Committee Expulsion & Fault Tolerance", function () { const { enclave: _enclave } = await ignition.deploy(EnclaveModule, { parameters: { Enclave: { - params: encodedE3ProgramParams, owner: ownerAddress, maxDuration: THIRTY_DAYS, registry: registryAddress, @@ -232,6 +231,7 @@ describe("Committee Expulsion & Fault Tolerance", function () { await registry.setSlashingManager(await slashingManager.getAddress()); await enclave.enableE3Program(await e3Program.getAddress()); + await enclave.setParamSet(0, encodedE3ProgramParams); await enclave.setDecryptionVerifier( encryptionSchemeId, await decryptionVerifier.getAddress(), @@ -315,7 +315,7 @@ describe("Committee Expulsion & Fault Tolerance", function () { committeeSize, inputWindow: [startTime + 100, startTime + ONE_DAY] as [number, number], e3Program: await e3Program.getAddress(), - e3ProgramParams: encodedE3ProgramParams, + paramSet: 0, computeProviderParams: abiCoder.encode( ["address"], [await decryptionVerifier.getAddress()], diff --git a/packages/enclave-sdk/src/contracts/contract-client.ts b/packages/enclave-sdk/src/contracts/contract-client.ts index c8cd8365f3..2665fb28b8 100644 --- a/packages/enclave-sdk/src/contracts/contract-client.ts +++ b/packages/enclave-sdk/src/contracts/contract-client.ts @@ -152,7 +152,7 @@ export class ContractClient { committeeSize: params.committeeSize, inputWindow: params.inputWindow, e3Program: params.e3Program, - e3ProgramParams: params.e3ProgramParams, + paramSet: params.paramSet, computeProviderParams: params.computeProviderParams, customParams: params.customParams || '0x', proofAggregationEnabled: params.proofAggregationEnabled ?? true, @@ -225,7 +225,7 @@ export class ContractClient { committeeSize: requestParams.committeeSize, inputWindow: requestParams.inputWindow, e3Program: requestParams.e3Program, - e3ProgramParams: requestParams.e3ProgramParams, + paramSet: requestParams.paramSet, computeProviderParams: requestParams.computeProviderParams, customParams: requestParams.customParams || '0x', proofAggregationEnabled: requestParams.proofAggregationEnabled ?? true, diff --git a/packages/enclave-sdk/src/contracts/types.ts b/packages/enclave-sdk/src/contracts/types.ts index 286042f3a8..51195b69a2 100644 --- a/packages/enclave-sdk/src/contracts/types.ts +++ b/packages/enclave-sdk/src/contracts/types.ts @@ -17,6 +17,11 @@ export enum CommitteeSize { Large = 3, } +export enum ParamSet { + Insecure512 = 0, + Secure8192 = 1, +} + export interface E3 { seed: bigint committeeSize: number @@ -24,7 +29,7 @@ export interface E3 { inputWindow: readonly [bigint, bigint] encryptionSchemeId: string e3Program: string - e3ProgramParams: string + paramSet: number decryptionVerifier: string committeePublicKey: string ciphertextOutput: string @@ -39,7 +44,7 @@ export interface E3RequestParams extends RequestParams { committeeSize: number inputWindow: readonly [bigint, bigint] e3Program: `0x${string}` - e3ProgramParams: `0x${string}` + paramSet: number computeProviderParams: `0x${string}` customParams?: `0x${string}` /** When true, ciphernodes generate wrapper/fold proofs for DKG proof aggregation. diff --git a/packages/enclave-sdk/src/enclave-sdk.ts b/packages/enclave-sdk/src/enclave-sdk.ts index 08fc78511e..021fc08503 100644 --- a/packages/enclave-sdk/src/enclave-sdk.ts +++ b/packages/enclave-sdk/src/enclave-sdk.ts @@ -137,7 +137,7 @@ export class EnclaveSDK { committeeSize: number inputWindow: [bigint, bigint] e3Program: `0x${string}` - e3ProgramParams: `0x${string}` + paramSet: number computeProviderParams: `0x${string}` customParams?: `0x${string}` proofAggregationEnabled?: boolean diff --git a/packages/enclave-sdk/src/events/types.ts b/packages/enclave-sdk/src/events/types.ts index 4da2c67268..791f3f4091 100644 --- a/packages/enclave-sdk/src/events/types.ts +++ b/packages/enclave-sdk/src/events/types.ts @@ -16,7 +16,7 @@ export enum EnclaveEventType { ENCRYPTION_SCHEME_DISABLED = 'EncryptionSchemeDisabled', CIPHERNODE_REGISTRY_SET = 'CiphernodeRegistrySet', MAX_DURATION_SET = 'MaxDurationSet', - ALLOWED_E3_PROGRAMS_PARAMS_SET = 'AllowedE3ProgramsParamsSet', + PARAM_SET_REGISTERED = 'ParamSetRegistered', OWNERSHIP_TRANSFERRED = 'OwnershipTransferred', INITIALIZED = 'Initialized', } @@ -41,7 +41,7 @@ export interface E3RequestedData { inputWindow: readonly [bigint, bigint] encryptionSchemeId: string e3Program: string - e3ProgramParams: string + paramSet: number decryptionVerifier: string committeePublicKey: string ciphertextOutput: string @@ -113,7 +113,7 @@ export interface EnclaveEventData { [EnclaveEventType.ENCRYPTION_SCHEME_DISABLED]: { encryptionSchemeId: string } [EnclaveEventType.CIPHERNODE_REGISTRY_SET]: { ciphernodeRegistry: string } [EnclaveEventType.MAX_DURATION_SET]: { maxDuration: bigint } - [EnclaveEventType.ALLOWED_E3_PROGRAMS_PARAMS_SET]: { e3ProgramParams: string[] } + [EnclaveEventType.PARAM_SET_REGISTERED]: { paramSet: number; encodedParams: string } [EnclaveEventType.OWNERSHIP_TRANSFERRED]: { previousOwner: string; newOwner: string } [EnclaveEventType.INITIALIZED]: { version: bigint } } diff --git a/templates/default/client/src/pages/steps/RequestComputation.tsx b/templates/default/client/src/pages/steps/RequestComputation.tsx index f506c4601f..b6141c3ba9 100644 --- a/templates/default/client/src/pages/steps/RequestComputation.tsx +++ b/templates/default/client/src/pages/steps/RequestComputation.tsx @@ -107,15 +107,13 @@ const RequestComputation: React.FC = () => { const publicClient = sdk.sdk.getPublicClient() const inputWindow = await calculateInputWindow(publicClient, 600) // 10 min - const thresholdBfvParams = await sdk.getThresholdBfvParamsSet() - const e3ProgramParams = encodeBfvParams(thresholdBfvParams) const computeProviderParams = encodeComputeProviderParams(DEFAULT_COMPUTE_PROVIDER_PARAMS) const requestParams = { committeeSize, inputWindow, e3Program: contracts.e3Program, - e3ProgramParams, + paramSet: 0, // ParamSet.Insecure512 computeProviderParams, proofAggregationEnabled: false, } diff --git a/templates/default/deployed_contracts.json b/templates/default/deployed_contracts.json index 07a0e0e735..8c2873bc99 100644 --- a/templates/default/deployed_contracts.json +++ b/templates/default/deployed_contracts.json @@ -1,21 +1,21 @@ { "localhost": { "PoseidonT3": { - "blockNumber": 4, + "blockNumber": 7, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 5, + "blockNumber": 8, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 6, + "blockNumber": 9, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { @@ -24,14 +24,14 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 8, + "blockNumber": 11, "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 9, + "blockNumber": 12, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "CiphernodeRegistryOwnable": { @@ -46,7 +46,7 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 10, + "blockNumber": 13, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "BondingRegistry": { @@ -68,7 +68,7 @@ "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 11, + "blockNumber": 14, "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { @@ -79,19 +79,16 @@ "e3RefundManager": "0x0000000000000000000000000000000000000001", "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "maxDuration": "2592000", - "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}", - "params": [ - "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000" - ] + "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" }, "proxyRecords": { - "initData": "0x01d12f1c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000", + "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 14, + "blockNumber": 17, "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "E3RefundManager": { @@ -107,56 +104,56 @@ "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, - "blockNumber": 16, + "blockNumber": 19, "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, "MockComputeProvider": { - "blockNumber": 18, - "address": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E" + "blockNumber": 21, + "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" }, "MockDecryptionVerifier": { - "blockNumber": 19, - "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" + "blockNumber": 22, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" }, "MockPkVerifier": { - "blockNumber": 20, - "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" + "blockNumber": 23, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" }, "MockE3Program": { - "blockNumber": 21, - "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + "blockNumber": 24, + "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" }, "ZKTranscriptLib": { - "blockNumber": 23, - "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" + "blockNumber": 26, + "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" }, "RecursiveAggregationFoldVerifier": { - "blockNumber": 24, - "address": "0x851356ae760d987E095750cCeb3bC6014560891C" + "blockNumber": 27, + "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" }, "ThresholdDecryptedSharesAggregationVerifier": { - "blockNumber": 25, - "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" + "blockNumber": 28, + "address": "0x998abeb3E57409262aE5b751f60747921B33613E" }, "ThresholdPkAggregationVerifier": { - "blockNumber": 26, - "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" + "blockNumber": 29, + "address": "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49" }, "BfvDecryptionVerifier": { - "blockNumber": 27, - "address": "0x998abeb3E57409262aE5b751f60747921B33613E" + "blockNumber": 30, + "address": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528" }, "BfvPkVerifier": { - "blockNumber": 29, - "address": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528" + "blockNumber": 32, + "address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF" }, "ImageID": { - "address": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf", - "blockNumber": 32 + "address": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", + "blockNumber": 35 }, "MyProgram": { - "address": "0x9d4454B023096f34B160D6B654540c56A1F81688", - "blockNumber": 34 + "address": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", + "blockNumber": 37 } } } \ No newline at end of file diff --git a/templates/default/enclave.config.yaml b/templates/default/enclave.config.yaml index 6d6ce9fe18..60c85ac8fe 100644 --- a/templates/default/enclave.config.yaml +++ b/templates/default/enclave.config.yaml @@ -4,22 +4,22 @@ chains: contracts: enclave: address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - deploy_block: 14 + deploy_block: 17 ciphernode_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 10 + deploy_block: 13 bonding_registry: address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - deploy_block: 11 + deploy_block: 14 slashing_manager: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" deploy_block: 13 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - deploy_block: 5 + deploy_block: 8 e3_program: - address: "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00" - deploy_block: 34 + address: "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570" + deploy_block: 37 program: dev: true nodes: diff --git a/templates/default/server/index.ts b/templates/default/server/index.ts index a27acb2cc9..fa383f36f1 100644 --- a/templates/default/server/index.ts +++ b/templates/default/server/index.ts @@ -18,7 +18,7 @@ import { MyProgram__factory } from '../types/factories/contracts' interface E3Session { e3Id: bigint expiration: bigint - e3ProgramParams?: string + paramSet?: number inputs: Array<{ data: string; index: bigint }> isProcessing: boolean isCompleted: boolean @@ -67,18 +67,31 @@ async function runProgram(e3Id: bigint): Promise { return } - let e3ProgramParams = session.e3ProgramParams - if (!e3ProgramParams) { - const sdk = await createPrivateSDK() - const e3Details = await sdk.getE3(e3Id) - e3ProgramParams = e3Details.e3ProgramParams - session.e3ProgramParams = e3ProgramParams - } + // Look up the encoded params from the on-chain paramSetRegistry + const sdk = await createPrivateSDK() + const e3Details = await sdk.getE3(e3Id) + const paramSetId = e3Details.paramSet + const publicClient = sdk.getPublicClient() + const { ENCLAVE_CONTRACT } = getCheckedEnvVars() + const e3ProgramParams = (await publicClient.readContract({ + address: ENCLAVE_CONTRACT as `0x${string}`, + abi: [ + { + name: 'paramSetRegistry', + type: 'function', + stateMutability: 'view', + inputs: [{ name: '', type: 'uint8' }], + outputs: [{ name: '', type: 'bytes' }], + }, + ], + functionName: 'paramSetRegistry', + args: [paramSetId], + })) as string const ciphertextInputs: Array<[string, number]> = session.inputs.map((input) => [input.data, Number(input.index)]) console.log(`🔄 Calling FHE runner for E3 ${e3Id}...`) - await callFheRunner(e3Id, e3ProgramParams!, ciphertextInputs) + await callFheRunner(e3Id, e3ProgramParams, ciphertextInputs) console.log(`✅ E3 ${e3Id} sent to FHE runner - awaiting callback`) } catch (error) { @@ -140,7 +153,7 @@ async function handleCommitteePublishedEvent(event: any) { if (!e3Sessions.has(e3Id.toString())) { e3Sessions.set(e3Id.toString(), { e3Id, - e3ProgramParams: e3.e3ProgramParams, + paramSet: e3.paramSet, expiration, inputs: [], isProcessing: false, diff --git a/templates/default/tests/integration.spec.ts b/templates/default/tests/integration.spec.ts index 1b49a1095c..94a487efff 100644 --- a/templates/default/tests/integration.spec.ts +++ b/templates/default/tests/integration.spec.ts @@ -191,9 +191,6 @@ describe('Integration', () => { const committeeSize = CommitteeSize.Micro const duration = 450 const inputWindow = await calculateInputWindow(publicClient, duration) - const thresholdBfvParams = await sdk.getThresholdBfvParamsSet() - const e3ProgramParams = encodeBfvParams(thresholdBfvParams) - const computeProviderParams = encodeComputeProviderParams( DEFAULT_COMPUTE_PROVIDER_PARAMS, true, // Mock the compute provider parameters, return 32 bytes of 0x00 @@ -207,7 +204,7 @@ describe('Integration', () => { committeeSize, inputWindow, e3Program: contracts.e3Program, - e3ProgramParams, + paramSet: 0, // ParamSet.Insecure512 computeProviderParams, proofAggregationEnabled: false, }