From 00893b763789ad1b20a457acfc1d024ae9ed7559 Mon Sep 17 00:00:00 2001 From: rudy Date: Wed, 22 Jan 2025 23:24:51 +0100 Subject: [PATCH] feat: listening events for TFHE operation on chain --- fhevm-engine/Cargo.toml | 2 +- fhevm-engine/listener/Cargo.toml | 22 + fhevm-engine/listener/README.md | 99 + fhevm-engine/listener/src/bin/main.rs | 215 ++ .../listener/src/contracts/ACL.json.abi | 663 +++++ .../src/contracts/TFHEExecutor.json.abi | 2353 +++++++++++++++++ fhevm-engine/listener/src/contracts/mod.rs | 20 + fhevm-engine/listener/src/lib.rs | 1 + 8 files changed, 3374 insertions(+), 1 deletion(-) create mode 100644 fhevm-engine/listener/Cargo.toml create mode 100644 fhevm-engine/listener/README.md create mode 100644 fhevm-engine/listener/src/bin/main.rs create mode 100644 fhevm-engine/listener/src/contracts/ACL.json.abi create mode 100644 fhevm-engine/listener/src/contracts/TFHEExecutor.json.abi create mode 100644 fhevm-engine/listener/src/contracts/mod.rs create mode 100644 fhevm-engine/listener/src/lib.rs diff --git a/fhevm-engine/Cargo.toml b/fhevm-engine/Cargo.toml index 8ed45b17..be4d80ae 100644 --- a/fhevm-engine/Cargo.toml +++ b/fhevm-engine/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["coprocessor", "executor", "fhevm-engine-common"] +members = ["coprocessor", "executor", "fhevm-engine-common", "listener"] [workspace.package] authors = ["Zama"] diff --git a/fhevm-engine/listener/Cargo.toml b/fhevm-engine/listener/Cargo.toml new file mode 100644 index 00000000..854c1fd6 --- /dev/null +++ b/fhevm-engine/listener/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "listener" +version = "0.0.1" +edition = "2021" + +[[bin]] +path = "src/bin/main.rs" +name = "listen" +test = false +bench = false + +[dependencies] +# workspace dependencies +alloy = { version = "=0.9.2", features = ["contract", "json", "providers", "provider-ws", "pubsub", "rpc-types", "sol-types"] } +alloy-rpc-types = "=0.9.2" +alloy-sol-types = "=0.8.19" +alloy-primitives = "=0.8.19" +alloy-provider = "=0.9.2" +clap = { workspace = true } +futures-util = "=0.3" +serde = { workspace = true } +tokio = { workspace = true } diff --git a/fhevm-engine/listener/README.md b/fhevm-engine/listener/README.md new file mode 100644 index 00000000..95214238 --- /dev/null +++ b/fhevm-engine/listener/README.md @@ -0,0 +1,99 @@ +# Listener + +The listener primary role is to observe the block chain execution and extend that execution off the chain. + +## How + +Our contracts actively emits events that forms the trace of a symbolic execution. These events can be observed via the blockchain node pubsub events feature. + +## Command-line + +WIP + +## Events in FHEVM + +### Blockchain Events +> Status: in progress +Blockchain events are used export the symbolic execution of TFHE operations from a blockchain node configured to accept pubsub requests. +A listener subscribe to the blockchain node and converts the events to a TFHE workload in a database. + +There are 3 types of events related to: +- TFHE operations +- ACL, can be used to preprocess ciphertext for certain use case +- Public and User Decryption + +### Database Events +> Status: proposal +Database events are used to hint the scheduler to dispath workload and to notice workload completion. + +> https://stackoverflow.com/questions/56747634/how-do-i-use-the-postgres-crate-to-receive-table-modification-events-from-postgr + +### Decryption Events +> Status: in progress + +### Overview FHEVM +> **_NOTE:_** Listener and scheduler could be in the same service.** +```mermaid +sequenceDiagram + participant BC App Node + participant Listener + participant Scheduler + participant DB + participant Coprocessor + + Listener-->>BC App Node: Subscribe Contract Events + Scheduler-->>DB: Subscribe Computations Insertions/Status
(proposal) + + loop Block Execution - Symbolic Operations + Note over BC App Node: Solidity traces a Symbolic Sequence + Note over BC App Node: TFHEExecutor contract + Note over BC App Node: ACL contract + end + + Note over BC App Node: End of Block Execution (MAYBE) + + BC App Node-)Listener: TFHE Operations Events + BC App Node-)Listener: ACL Events + + Listener->>DB: Insert TFHE Operations + DB-)Scheduler: Notice TFHE Operations Insertions
(proposal) + Scheduler-)Coprocessor: THFE Operation Workload + BC App Node-)Listener: Decryption Events + + loop FHE Computation + Coprocessor -->> DB: Read Operands Ciphertexts + Note over Coprocessor: TFHE Computation + Coprocessor -->> DB: Write Result Ciphertext + Coprocessor-->>DB: Mark TFHE Operation as Done + end + DB-)Scheduler: Notice TFHE Operations Status
(proposal) +``` + +### Overview Relayer (maybe incorrect to be refined) + +```mermaid +sequenceDiagram + participant Relayer + participant Listener + participant Scheduler + participant DB + participant Coprocessor + + Note over Listener: THEFE Operations Events + Note over Listener: Decryption Events + + Listener->>DB: Insert TFHE Operations + Listener->>Relayer: Decryption Workload + DB-)Scheduler: Notice TFHE Operations Insertions
(proposal) + Scheduler-)Coprocessor: THEFE Operation Workload + + loop FHE Computation + Coprocessor -->> DB: Read Operands Ciphertexts + Note over Coprocessor: TFHE Computation + Coprocessor -->> DB: Write Result Ciphertexts + Coprocessor-->>DB: TFHE Operation Done + end + DB-)Scheduler: Notice TFHE Operations Status
(proposal) + Scheduler-)Relayer: Notice Ciphertext ready for decryption +``` + diff --git a/fhevm-engine/listener/src/bin/main.rs b/fhevm-engine/listener/src/bin/main.rs new file mode 100644 index 00000000..aff5c363 --- /dev/null +++ b/fhevm-engine/listener/src/bin/main.rs @@ -0,0 +1,215 @@ +use futures_util::stream::StreamExt; +use std::str::FromStr; +use std::time::Duration; + +use alloy::primitives::Address; +use alloy::providers::{Provider, ProviderBuilder, RootProvider, WsConnect}; +use alloy::pubsub::{PubSubFrontend, SubscriptionStream}; +use alloy::rpc::types::{BlockNumberOrTag, Filter}; +use alloy_rpc_types::Log; +use alloy_sol_types::SolEventInterface; + +use clap::Parser; + +use listener::contracts::{AclContract, TfheContract}; + +const DEFAULT_BLOCK: BlockNumberOrTag = BlockNumberOrTag::Latest; +const DEFAULT_CATCHUP: u64 = 5; + +#[derive(Parser, Debug, Clone)] +#[command(version, about, long_about = None)] +pub struct Args { + #[arg(long, default_value = "ws://0.0.0.0:8746")] + pub url: String, + + #[arg(long, default_value = "false")] + pub ignore_tfhe_events: bool, + + #[arg(long, default_value = "false")] + pub ignore_acl_events: bool, + + #[arg(long, default_value = None)] + pub acl_contract_address: Option, + + #[arg(long, default_value = None)] + pub tfhe_contract_address: Option, + + #[arg(long, default_value = None)] + pub database_url: Option, + + #[arg(long, default_value = None, help = "Can be negative from last block", allow_hyphen_values = true)] + pub start_at_block: Option, + + #[arg(long, default_value = None)] + pub end_at_block: Option, +} + +// TODO: to merge with Levent works +struct InfiniteLogIter { + url: String, + contract_addresses: Vec
, + stream: Option>, + provider: Option>, // required to maintain the stream + last_seen_block: Option, + start_at_block: Option, + end_at_block: Option, +} + +impl InfiniteLogIter { + fn new(args: &Args) -> Self { + let mut contract_addresses = vec![]; + if let Some(acl_contract_address) = &args.acl_contract_address { + contract_addresses.push(Address::from_str(acl_contract_address).unwrap()); + }; + if let Some(tfhe_contract_address) = &args.tfhe_contract_address { + contract_addresses.push(Address::from_str(tfhe_contract_address).unwrap()); + }; + Self { + url: args.url.clone(), + contract_addresses: contract_addresses, + stream: None, + provider: None, + last_seen_block: None, + start_at_block: args.start_at_block, + end_at_block: args.end_at_block, + } + } + + async fn catchup_block_from( + &self, + provider: &RootProvider, + ) -> BlockNumberOrTag { + if let Some(last_seen_block) = self.last_seen_block { + return BlockNumberOrTag::Number(last_seen_block - 1); + } + if let Some(start_at_block) = self.start_at_block { + if start_at_block >= 0 { + return BlockNumberOrTag::Number(start_at_block.try_into().unwrap()); + } + } + let Ok(last_block) = provider.get_block_number().await else { + return BlockNumberOrTag::Earliest; // should not happend + }; + let catch_size = if let Some(start_at_block) = self.start_at_block { + (-start_at_block).try_into().unwrap() + } else { + DEFAULT_CATCHUP + }; + return BlockNumberOrTag::Number(last_block - catch_size.min(last_block)); + } + + async fn new_log_stream(&mut self, not_initialized: bool) { + let mut retry = 20; + loop { + let ws = WsConnect::new(&self.url); + match ProviderBuilder::new().on_ws(ws).await { + Ok(provider) => { + let catch_up_from = self.catchup_block_from(&provider).await; + if not_initialized { + eprintln!("Catchup from {:?}", catch_up_from); + } + let mut filter = Filter::new().from_block(catch_up_from); + if let Some(end_at_block) = self.end_at_block { + filter = filter.to_block(BlockNumberOrTag::Number(end_at_block)); + // inclusive + } + if !self.contract_addresses.is_empty() { + filter = filter.address(self.contract_addresses.clone()) + } + eprintln!("Listening on {}", &self.url); + eprintln!("Contracts {:?}", &self.contract_addresses); + self.stream = Some( + provider + .subscribe_logs(&filter) + .await + .expect("BLA2") + .into_stream(), + ); + self.provider = Some(provider); + return; + } + Err(err) => { + let delay = if not_initialized { + if retry == 0 { + panic!("Cannot connect to {} due to {err}.", &self.url) + } + 5 + } else { + 1 + }; + if not_initialized { + eprintln!("Cannot connect to {} due to {err}. Will retry in {delay} secs, {retry} times.", &self.url); + } else { + eprintln!("Cannot connect to {} due to {err}. Will retry in {delay} secs, indefinitively.", &self.url); + } + retry -= 1; + tokio::time::sleep(Duration::from_secs(delay)).await; + } + } + } + } + + async fn next(&mut self) -> Option { + let mut not_initialized = true; + loop { + let Some(stream) = &mut self.stream else { + self.new_log_stream(not_initialized).await; + not_initialized = false; + continue; + }; + let Some(log) = stream.next().await else { + // the stream ends, could be a restart of the full node, or just a temporary gap + self.stream = None; + if let (Some(end_at_block), Some(last_seen_block)) = + (self.end_at_block, self.last_seen_block) + { + if end_at_block == last_seen_block { + eprintln!("Nothing to read, reached end of block range"); + return None; + } + } + eprintln!("Nothing to read, retrying"); + tokio::time::sleep(Duration::from_secs(1)).await; + continue; + }; + return Some(log); + } + } +} + +#[tokio::main] +async fn main() -> () { + let args = Args::parse(); + let mut log_iter = InfiniteLogIter::new(&args); + if let Some(acl_contract_address) = &args.acl_contract_address { + if let Err(err) = Address::from_str(acl_contract_address) { + panic!("Invalid acl contract address: {err}"); + }; + }; + if let Some(tfhe_contract_address) = &args.tfhe_contract_address { + if let Err(err) = Address::from_str(tfhe_contract_address) { + panic!("Invalid tfhe contract address: {err}"); + }; + } + + log_iter.new_log_stream(true).await; + while let Some(log) = log_iter.next().await { + if let Some(block_number) = log.block_number { + eprintln!("Event at block: {}", { block_number }); + log_iter.last_seen_block = Some(block_number); + } + if !args.ignore_tfhe_events { + if let Ok(event) = TfheContract::TfheContractEvents::decode_log(&log.inner, true) { + // TODO: filter on contract address if known + println!("TFHE {event:#?}"); + continue; + } + } + if !args.ignore_tfhe_events { + if let Ok(event) = AclContract::AclContractEvents::decode_log(&log.inner, true) { + println!("ACL {event:#?}"); + continue; + } + } + } +} diff --git a/fhevm-engine/listener/src/contracts/ACL.json.abi b/fhevm-engine/listener/src/contracts/ACL.json.abi new file mode 100644 index 00000000..8f4b2ed6 --- /dev/null +++ b/fhevm-engine/listener/src/contracts/ACL.json.abi @@ -0,0 +1,663 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ACL", + "sourceName": "contracts/ACL.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "AlreadyDelegated", + "type": "error" + }, + { + "inputs": [], + "name": "ContractAddressesIsEmpty", + "type": "error" + }, + { + "inputs": [], + "name": "ContractAddressesMaxLengthExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [], + "name": "HandlesListIsEmpty", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "NotDelegatedYet", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "SenderCannotBeContractAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "handle", + "type": "uint256" + } + ], + "name": "Allowed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "handlesList", + "type": "uint256[]" + } + ], + "name": "AllowedForDecryption", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "contractAddresses", + "type": "address[]" + } + ], + "name": "NewDelegation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "contractAddresses", + "type": "address[]" + } + ], + "name": "RevokedDelegation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "allow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "handlesList", + "type": "uint256[]" + } + ], + "name": "allowForDecryption", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "allowTransient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "allowedOnBehalf", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "allowedTransient", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cleanTransientStorage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "address[]", + "name": "contractAddresses", + "type": "address[]" + } + ], + "name": "delegateAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getTFHEExecutorAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVersion", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + } + ], + "name": "isAllowedForDecryption", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "persistAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "address[]", + "name": "contractAddresses", + "type": "address[]" + } + ], + "name": "revokeDelegation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x60a060405230608052348015610013575f80fd5b5061001c610021565b6100d3565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100715760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100d05780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161191b6100f95f395f8181610f0d01528181610f36015261109b015261191b5ff3fe608060405260043610610162575f3560e01c806365d0509c116100c65780638da5cb5b1161007c578063ccd9a7cd11610057578063ccd9a7cd14610436578063e30c397814610455578063f2fde38b14610469575f80fd5b80638da5cb5b1461039c578063a90cd91d146103c8578063ad3cb1cc146103ee575f80fd5b806379ba5097116100ac57806379ba50971461034a5780637a9a598e1461035e5780638d9c9c921461037d575f80fd5b806365d0509c14610317578063715018a614610336575f80fd5b806352d1902d1161011b578063557e100411610101578063557e10041461028c5780635faa299a146102ab5780636330a709146102ca575f80fd5b806352d1902d1461024b578063531efc921461026d575f80fd5b806335334c231161014b57806335334c23146101b157806337e6b44f146101c55780634f1ef28614610238575f80fd5b8063088563e8146101665780630d8e6e2c14610187575b5f80fd5b348015610171575f80fd5b506101856101803660046114f9565b610488565b005b348015610192575f80fd5b5061019b610655565b6040516101a891906115c6565b60405180910390f35b3480156101bc575f80fd5b506101856106b6565b3480156101d0575f80fd5b506102286101df3660046115f8565b5f9182527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60405190151581526020016101a8565b610185610246366004611622565b6106e0565b348015610256575f80fd5b5061025f6106ff565b6040519081526020016101a8565b348015610278575f80fd5b506101856102873660046114f9565b61072d565b348015610297575f80fd5b506101856102a63660046116c2565b61097c565b3480156102b6575f80fd5b506102286102c53660046115f8565b610a78565b3480156102d5575f80fd5b506102286102e436600461174e565b5f9081527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc01602052604090205460ff1690565b348015610322575f80fd5b506101856103313660046115f8565b610ad5565b348015610341575f80fd5b50610185610b81565b348015610355575f80fd5b50610185610b94565b348015610369575f80fd5b506102286103783660046115f8565b610bdc565b348015610388575f80fd5b506101856103973660046115f8565b610c2f565b3480156103a7575f80fd5b506103b0610ccf565b6040516001600160a01b0390911681526020016101a8565b3480156103d3575f80fd5b50734e142887e3dc6e414a9b260a1034d20c9b4eb11f6103b0565b3480156103f9575f80fd5b5061019b6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b348015610441575f80fd5b50610228610450366004611765565b610d03565b348015610460575f80fd5b506103b0610db8565b348015610474575f80fd5b506101856104833660046117af565b610de0565b80515f8190036104ab576040516317d7ad0760e21b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b8281101561060357335f90815260028301602090815260408083206001600160a01b038916845290915281208551909190869084908110610511576105116117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f205460ff1615610590578484828151811061054f5761054f6117c8565b6020026020010151604051632210106160e01b81526004016105879291906001600160a01b0392831681529116602082015260400190565b60405180910390fd5b335f90815260028301602090815260408083206001600160a01b03891684529091528120855182908790859081106105ca576105ca6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff19169115159190911790556001016104ce565b50836001600160a01b0316336001600160a01b03167f7c0a18a6132447b7c9f34ae509fec1dba0cb0ff0bdd1704b99779a1c744a138e8560405161064791906117dc565b60405180910390a350505050565b6060604051806040016040528060038152602001621050d360ea1b81525061067c5f610e65565b6106866001610e65565b61068f5f610e65565b6040516020016106a29493929190611828565b604051602081830303815290604052905090565b5f5c5f805d600190810190805b828110156106db57805c5f825d5f815d5081016106c3565b505050565b6106e8610f02565b6106f182610fb9565b6106fb8282610fc1565b5050565b5f610708611090565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b80515f819003610750576040516317d7ad0760e21b815260040160405180910390fd5b600a811115610772576040516365ac366b60e11b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b8281101561093857336001600160a01b03168482815181106107b9576107b96117c8565b60200260200101516001600160a01b031603610812578381815181106107e1576107e16117c8565b6020026020010151604051630c24836b60e31b815260040161058791906001600160a01b0391909116815260200190565b335f90815260028301602090815260408083206001600160a01b03891684529091528120855190919086908490811061084d5761084d6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f205460ff16156108c3578484828151811061088b5761088b6117c8565b6020026020010151604051633e39e40f60e21b81526004016105879291906001600160a01b0392831681529116602082015260400190565b335f90815260028301602090815260408083206001600160a01b038916845290915281208551600192908790859081106108ff576108ff6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff1916911515919091179055600101610795565b50836001600160a01b0316336001600160a01b03167f6ac533ce8df9b9d2a4842715e991ef317c4a8148d2dbc0a5109ce6979de353e58560405161064791906117dc565b80515f81900361099f5760405163385e8ccb60e11b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b82811015610a31575f8482815181106109dd576109dd6117c8565b602002602001015190506109f18133610a78565b610a10576040516368692cbb60e11b8152336004820152602401610587565b5f90815260018381016020526040909120805460ff191682179055016109c2565b50336001600160a01b03167f9e815ea370c1c2a5e7343bc18af3aa404bcb8eb2a8421cba4d11cb810032008784604051610a6b91906118a5565b60405180910390a2505050565b5f610a838383610bdc565b80610ace57505f8381527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602090815260408083206001600160a01b038616845290915290205460ff165b9392505050565b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00610b008333610a78565b610b1f576040516368692cbb60e11b8152336004820152602401610587565b5f838152602082815260408083206001600160a01b03861680855290835292819020805460ff191660011790555185815233917e1184123078cd58061e15db3b045089949811fe5ca4206cf0eab78f30f58b1b910160405180910390a3505050565b610b896110d9565b610b925f61110b565b565b3380610b9e610db8565b6001600160a01b031614610bd05760405163118cdaa760e01b81526001600160a01b0382166004820152602401610587565b610bd98161110b565b50565b5f805f8484604051602001610c0d92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051808303601f1901815291905280516020909101205c95945050505050565b33734e142887e3dc6e414a9b260a1034d20c9b4eb11f14610c7357610c548233610a78565b610c73576040516368692cbb60e11b8152336004820152602401610587565b5f8282604051602001610ca292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012090506001815d60015f5c0181815d805f5d50505050565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f8381527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602081815260408084206001600160a01b038616855290915282205460ff168015610d7257505f858152602082815260408083206001600160a01b038816845290915290205460ff165b8015610dae57506001600160a01b038084165f90815260028301602090815260408083208a8516845282528083209388168352929052205460ff165b9695505050505050565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610cf3565b610de86110d9565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b0383169081178255610e2c610ccf565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b60605f610e7183611143565b60010190505f8167ffffffffffffffff811115610e9057610e90611491565b6040519080825280601f01601f191660200182016040528015610eba576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610ec457509392505050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480610f9b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610f8f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614155b15610b925760405163703e46dd60e11b815260040160405180910390fd5b610bd96110d9565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561101b575060408051601f3d908101601f19168201909252611018918101906118dc565b60015b61104357604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610587565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461108657604051632a87526960e21b815260048101829052602401610587565b6106db8383611225565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b925760405163703e46dd60e11b815260040160405180910390fd5b336110e2610ccf565b6001600160a01b031614610b925760405163118cdaa760e01b8152336004820152602401610587565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b03191681556106fb8261127a565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061118b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106111b7576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106111d557662386f26fc10000830492506010015b6305f5e10083106111ed576305f5e100830492506008015b612710831061120157612710830492506004015b60648310611213576064830492506002015b600a831061121f576001015b92915050565b61122e826112ea565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611272576106db8282611360565b6106fb6113d2565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b806001600160a01b03163b5f0361131f57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610587565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b03168460405161137c91906118f3565b5f60405180830381855af49150503d805f81146113b4576040519150601f19603f3d011682016040523d82523d5f602084013e6113b9565b606091505b50915091506113c98583836113f1565b95945050505050565b3415610b925760405163b398979f60e01b815260040160405180910390fd5b606082611406576114018261144d565b610ace565b815115801561141d57506001600160a01b0384163b155b1561144657604051639996b31560e01b81526001600160a01b0385166004820152602401610587565b5092915050565b80511561145d5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160a01b038116811461148c575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156114ce576114ce611491565b604052919050565b5f67ffffffffffffffff8211156114ef576114ef611491565b5060051b60200190565b5f806040838503121561150a575f80fd5b61151383611476565b915060208084013567ffffffffffffffff81111561152f575f80fd5b8401601f8101861361153f575f80fd5b803561155261154d826114d6565b6114a5565b81815260059190911b82018301908381019088831115611570575f80fd5b928401925b828410156115955761158684611476565b82529284019290840190611575565b80955050505050509250929050565b5f5b838110156115be5781810151838201526020016115a6565b50505f910152565b602081525f82518060208401526115e48160408501602087016115a4565b601f01601f19169190910160400192915050565b5f8060408385031215611609575f80fd5b8235915061161960208401611476565b90509250929050565b5f8060408385031215611633575f80fd5b61163c83611476565b915060208084013567ffffffffffffffff80821115611659575f80fd5b818601915086601f83011261166c575f80fd5b81358181111561167e5761167e611491565b611690601f8201601f191685016114a5565b915080825287848285010111156116a5575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f60208083850312156116d3575f80fd5b823567ffffffffffffffff8111156116e9575f80fd5b8301601f810185136116f9575f80fd5b803561170761154d826114d6565b81815260059190911b82018301908381019087831115611725575f80fd5b928401925b828410156117435783358252928401929084019061172a565b979650505050505050565b5f6020828403121561175e575f80fd5b5035919050565b5f805f8060808587031215611778575f80fd5b61178185611476565b93506020850135925061179660408601611476565b91506117a460608601611476565b905092959194509250565b5f602082840312156117bf575f80fd5b610ace82611476565b634e487b7160e01b5f52603260045260245ffd5b602080825282518282018190525f9190848201906040850190845b8181101561181c5783516001600160a01b0316835292840192918401916001016117f7565b50909695505050505050565b5f8551611839818460208a016115a4565b61103b60f11b9083019081528551611858816002840160208a016115a4565b808201915050601760f91b806002830152855161187c816003850160208a016115a4565b600392019182015283516118978160048401602088016115a4565b016004019695505050505050565b602080825282518282018190525f9190848201906040850190845b8181101561181c578351835292840192918401916001016118c0565b5f602082840312156118ec575f80fd5b5051919050565b5f82516119048184602087016115a4565b919091019291505056fea164736f6c6343000818000a", + "deployedBytecode": "0x608060405260043610610162575f3560e01c806365d0509c116100c65780638da5cb5b1161007c578063ccd9a7cd11610057578063ccd9a7cd14610436578063e30c397814610455578063f2fde38b14610469575f80fd5b80638da5cb5b1461039c578063a90cd91d146103c8578063ad3cb1cc146103ee575f80fd5b806379ba5097116100ac57806379ba50971461034a5780637a9a598e1461035e5780638d9c9c921461037d575f80fd5b806365d0509c14610317578063715018a614610336575f80fd5b806352d1902d1161011b578063557e100411610101578063557e10041461028c5780635faa299a146102ab5780636330a709146102ca575f80fd5b806352d1902d1461024b578063531efc921461026d575f80fd5b806335334c231161014b57806335334c23146101b157806337e6b44f146101c55780634f1ef28614610238575f80fd5b8063088563e8146101665780630d8e6e2c14610187575b5f80fd5b348015610171575f80fd5b506101856101803660046114f9565b610488565b005b348015610192575f80fd5b5061019b610655565b6040516101a891906115c6565b60405180910390f35b3480156101bc575f80fd5b506101856106b6565b3480156101d0575f80fd5b506102286101df3660046115f8565b5f9182527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60405190151581526020016101a8565b610185610246366004611622565b6106e0565b348015610256575f80fd5b5061025f6106ff565b6040519081526020016101a8565b348015610278575f80fd5b506101856102873660046114f9565b61072d565b348015610297575f80fd5b506101856102a63660046116c2565b61097c565b3480156102b6575f80fd5b506102286102c53660046115f8565b610a78565b3480156102d5575f80fd5b506102286102e436600461174e565b5f9081527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc01602052604090205460ff1690565b348015610322575f80fd5b506101856103313660046115f8565b610ad5565b348015610341575f80fd5b50610185610b81565b348015610355575f80fd5b50610185610b94565b348015610369575f80fd5b506102286103783660046115f8565b610bdc565b348015610388575f80fd5b506101856103973660046115f8565b610c2f565b3480156103a7575f80fd5b506103b0610ccf565b6040516001600160a01b0390911681526020016101a8565b3480156103d3575f80fd5b50734e142887e3dc6e414a9b260a1034d20c9b4eb11f6103b0565b3480156103f9575f80fd5b5061019b6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b348015610441575f80fd5b50610228610450366004611765565b610d03565b348015610460575f80fd5b506103b0610db8565b348015610474575f80fd5b506101856104833660046117af565b610de0565b80515f8190036104ab576040516317d7ad0760e21b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b8281101561060357335f90815260028301602090815260408083206001600160a01b038916845290915281208551909190869084908110610511576105116117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f205460ff1615610590578484828151811061054f5761054f6117c8565b6020026020010151604051632210106160e01b81526004016105879291906001600160a01b0392831681529116602082015260400190565b60405180910390fd5b335f90815260028301602090815260408083206001600160a01b03891684529091528120855182908790859081106105ca576105ca6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff19169115159190911790556001016104ce565b50836001600160a01b0316336001600160a01b03167f7c0a18a6132447b7c9f34ae509fec1dba0cb0ff0bdd1704b99779a1c744a138e8560405161064791906117dc565b60405180910390a350505050565b6060604051806040016040528060038152602001621050d360ea1b81525061067c5f610e65565b6106866001610e65565b61068f5f610e65565b6040516020016106a29493929190611828565b604051602081830303815290604052905090565b5f5c5f805d600190810190805b828110156106db57805c5f825d5f815d5081016106c3565b505050565b6106e8610f02565b6106f182610fb9565b6106fb8282610fc1565b5050565b5f610708611090565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b80515f819003610750576040516317d7ad0760e21b815260040160405180910390fd5b600a811115610772576040516365ac366b60e11b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b8281101561093857336001600160a01b03168482815181106107b9576107b96117c8565b60200260200101516001600160a01b031603610812578381815181106107e1576107e16117c8565b6020026020010151604051630c24836b60e31b815260040161058791906001600160a01b0391909116815260200190565b335f90815260028301602090815260408083206001600160a01b03891684529091528120855190919086908490811061084d5761084d6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f205460ff16156108c3578484828151811061088b5761088b6117c8565b6020026020010151604051633e39e40f60e21b81526004016105879291906001600160a01b0392831681529116602082015260400190565b335f90815260028301602090815260408083206001600160a01b038916845290915281208551600192908790859081106108ff576108ff6117c8565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff1916911515919091179055600101610795565b50836001600160a01b0316336001600160a01b03167f6ac533ce8df9b9d2a4842715e991ef317c4a8148d2dbc0a5109ce6979de353e58560405161064791906117dc565b80515f81900361099f5760405163385e8ccb60e11b815260040160405180910390fd5b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc005f5b82811015610a31575f8482815181106109dd576109dd6117c8565b602002602001015190506109f18133610a78565b610a10576040516368692cbb60e11b8152336004820152602401610587565b5f90815260018381016020526040909120805460ff191682179055016109c2565b50336001600160a01b03167f9e815ea370c1c2a5e7343bc18af3aa404bcb8eb2a8421cba4d11cb810032008784604051610a6b91906118a5565b60405180910390a2505050565b5f610a838383610bdc565b80610ace57505f8381527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602090815260408083206001600160a01b038616845290915290205460ff165b9392505050565b7fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00610b008333610a78565b610b1f576040516368692cbb60e11b8152336004820152602401610587565b5f838152602082815260408083206001600160a01b03861680855290835292819020805460ff191660011790555185815233917e1184123078cd58061e15db3b045089949811fe5ca4206cf0eab78f30f58b1b910160405180910390a3505050565b610b896110d9565b610b925f61110b565b565b3380610b9e610db8565b6001600160a01b031614610bd05760405163118cdaa760e01b81526001600160a01b0382166004820152602401610587565b610bd98161110b565b50565b5f805f8484604051602001610c0d92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051808303601f1901815291905280516020909101205c95945050505050565b33734e142887e3dc6e414a9b260a1034d20c9b4eb11f14610c7357610c548233610a78565b610c73576040516368692cbb60e11b8152336004820152602401610587565b5f8282604051602001610ca292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6040516020818303038152906040528051906020012090506001815d60015f5c0181815d805f5d50505050565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f8381527fa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00602081815260408084206001600160a01b038616855290915282205460ff168015610d7257505f858152602082815260408083206001600160a01b038816845290915290205460ff165b8015610dae57506001600160a01b038084165f90815260028301602090815260408083208a8516845282528083209388168352929052205460ff165b9695505050505050565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610cf3565b610de86110d9565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b0383169081178255610e2c610ccf565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b60605f610e7183611143565b60010190505f8167ffffffffffffffff811115610e9057610e90611491565b6040519080825280601f01601f191660200182016040528015610eba576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610ec457509392505050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480610f9b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610f8f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614155b15610b925760405163703e46dd60e11b815260040160405180910390fd5b610bd96110d9565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561101b575060408051601f3d908101601f19168201909252611018918101906118dc565b60015b61104357604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610587565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461108657604051632a87526960e21b815260048101829052602401610587565b6106db8383611225565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b925760405163703e46dd60e11b815260040160405180910390fd5b336110e2610ccf565b6001600160a01b031614610b925760405163118cdaa760e01b8152336004820152602401610587565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b03191681556106fb8261127a565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061118b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106111b7576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106111d557662386f26fc10000830492506010015b6305f5e10083106111ed576305f5e100830492506008015b612710831061120157612710830492506004015b60648310611213576064830492506002015b600a831061121f576001015b92915050565b61122e826112ea565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611272576106db8282611360565b6106fb6113d2565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b806001600160a01b03163b5f0361131f57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610587565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b03168460405161137c91906118f3565b5f60405180830381855af49150503d805f81146113b4576040519150601f19603f3d011682016040523d82523d5f602084013e6113b9565b606091505b50915091506113c98583836113f1565b95945050505050565b3415610b925760405163b398979f60e01b815260040160405180910390fd5b606082611406576114018261144d565b610ace565b815115801561141d57506001600160a01b0384163b155b1561144657604051639996b31560e01b81526001600160a01b0385166004820152602401610587565b5092915050565b80511561145d5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160a01b038116811461148c575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156114ce576114ce611491565b604052919050565b5f67ffffffffffffffff8211156114ef576114ef611491565b5060051b60200190565b5f806040838503121561150a575f80fd5b61151383611476565b915060208084013567ffffffffffffffff81111561152f575f80fd5b8401601f8101861361153f575f80fd5b803561155261154d826114d6565b6114a5565b81815260059190911b82018301908381019088831115611570575f80fd5b928401925b828410156115955761158684611476565b82529284019290840190611575565b80955050505050509250929050565b5f5b838110156115be5781810151838201526020016115a6565b50505f910152565b602081525f82518060208401526115e48160408501602087016115a4565b601f01601f19169190910160400192915050565b5f8060408385031215611609575f80fd5b8235915061161960208401611476565b90509250929050565b5f8060408385031215611633575f80fd5b61163c83611476565b915060208084013567ffffffffffffffff80821115611659575f80fd5b818601915086601f83011261166c575f80fd5b81358181111561167e5761167e611491565b611690601f8201601f191685016114a5565b915080825287848285010111156116a5575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f60208083850312156116d3575f80fd5b823567ffffffffffffffff8111156116e9575f80fd5b8301601f810185136116f9575f80fd5b803561170761154d826114d6565b81815260059190911b82018301908381019087831115611725575f80fd5b928401925b828410156117435783358252928401929084019061172a565b979650505050505050565b5f6020828403121561175e575f80fd5b5035919050565b5f805f8060808587031215611778575f80fd5b61178185611476565b93506020850135925061179660408601611476565b91506117a460608601611476565b905092959194509250565b5f602082840312156117bf575f80fd5b610ace82611476565b634e487b7160e01b5f52603260045260245ffd5b602080825282518282018190525f9190848201906040850190845b8181101561181c5783516001600160a01b0316835292840192918401916001016117f7565b50909695505050505050565b5f8551611839818460208a016115a4565b61103b60f11b9083019081528551611858816002840160208a016115a4565b808201915050601760f91b806002830152855161187c816003850160208a016115a4565b600392019182015283516118978160048401602088016115a4565b016004019695505050505050565b602080825282518282018190525f9190848201906040850190845b8181101561181c578351835292840192918401916001016118c0565b5f602082840312156118ec575f80fd5b5051919050565b5f82516119048184602087016115a4565b919091019291505056fea164736f6c6343000818000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/fhevm-engine/listener/src/contracts/TFHEExecutor.json.abi b/fhevm-engine/listener/src/contracts/TFHEExecutor.json.abi new file mode 100644 index 00000000..b8f41267 --- /dev/null +++ b/fhevm-engine/listener/src/contracts/TFHEExecutor.json.abi @@ -0,0 +1,2353 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TFHEExecutor", + "sourceName": "contracts/TFHEExecutor.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "handle", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "ACLNotAllowed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [], + "name": "DivisionByZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [], + "name": "IncompatibleTypes", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "typeOf", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "InvalidByteLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidType", + "type": "error" + }, + { + "inputs": [], + "name": "IsNotScalar", + "type": "error" + }, + { + "inputs": [], + "name": "IsScalar", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "NotPowerOfTwo", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "SecondOperandIsNotScalar", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "UnsupportedType", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ct", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "Cast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheAdd", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheBitAnd", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheBitOr", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheBitXor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheDiv", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheEq", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "rhs", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheEqBytes", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheGe", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheGt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "control", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ifTrue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ifFalse", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheIfThenElse", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheLe", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheLt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheMax", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheMin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheMul", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheNe", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "rhs", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheNeBytes", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ct", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheNeg", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ct", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheNot", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "randType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "bytes16", + "name": "seed", + "type": "bytes16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheRand", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upperBound", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "randType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "bytes16", + "name": "seed", + "type": "bytes16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheRandBounded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheRem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheRotl", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheRotr", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheShl", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheShr", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "FheSub", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "TrivialEncrypt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pt", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "TrivialEncryptBytes", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "inputHandle", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "userAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "inputProof", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes1", + "name": "inputType", + "type": "bytes1" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "name": "VerifyCiphertext", + "type": "event" + }, + { + "inputs": [], + "name": "HANDLE_VERSION", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ct", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + } + ], + "name": "cast", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheAdd", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheBitAnd", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheBitOr", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheBitXor", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheDiv", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheEq", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "rhs", + "type": "bytes" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheEq", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheGe", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheGt", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "control", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ifTrue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ifFalse", + "type": "uint256" + } + ], + "name": "fheIfThenElse", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheLe", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheLt", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheMax", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheMin", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheMul", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "rhs", + "type": "bytes" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheNe", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheNe", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ct", + "type": "uint256" + } + ], + "name": "fheNeg", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ct", + "type": "uint256" + } + ], + "name": "fheNot", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "randType", + "type": "bytes1" + } + ], + "name": "fheRand", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "upperBound", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "randType", + "type": "bytes1" + } + ], + "name": "fheRandBounded", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheRem", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheRotl", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheRotr", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheShl", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheShr", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lhs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rhs", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "scalarByte", + "type": "bytes1" + } + ], + "name": "fheSub", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getACLAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFHEGasLimitAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputVerifierAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVersion", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pt", + "type": "bytes" + }, + { + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + } + ], + "name": "trivialEncrypt", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pt", + "type": "uint256" + }, + { + "internalType": "bytes1", + "name": "toType", + "type": "bytes1" + } + ], + "name": "trivialEncrypt", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "inputHandle", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "userAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "inputProof", + "type": "bytes" + }, + { + "internalType": "bytes1", + "name": "inputType", + "type": "bytes1" + } + ], + "name": "verifyCiphertext", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60a06040523060805234801562000014575f80fd5b506200001f6200002f565b620000296200002f565b620000e3565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000805760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000e05780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161461e6200010a5f395f81816121a1015281816121ca0152612334015261461e5ff3fe6080604052600436106102d7575f3560e01c806389a4314b1161017b578063cb3b9407116100d1578063ec4057dc11610087578063f6859bdc11610062578063f6859bdc146107f0578063f953e42714610816578063fa33b7af14610835575f80fd5b8063ec4057dc14610793578063eee1833c146107b2578063f2fde38b146107d1575f80fd5b8063e0c5cbb3116100b7578063e0c5cbb314610741578063e30c397814610760578063e71746b814610774575f80fd5b8063cb3b940714610703578063e0c516ae14610722575f80fd5b8063a86e9de511610131578063a8c7c2c11161010c578063a8c7c2c114610676578063ad3cb1cc1461069c578063bc47139a146106e4575f80fd5b8063a86e9de514610619578063a87deac414610638578063a8b42a8914610657575f80fd5b80638da5cb5b116101615780638da5cb5b146105c7578063900d294e146105db5780639675211f146105fa575f80fd5b806389a4314b146105895780638c14cc21146105a8575f80fd5b80634be68d2011610230578063694daf72116101e6578063715018a6116101c1578063715018a61461054257806379ba509714610556578063816d57d31461056a575f80fd5b8063694daf72146104df5780636a8c8eb4146104fe5780636be3175814610523575f80fd5b806352d1902d1161021657806352d1902d14610479578063601303d11461048d578063666a3588146104c0575f80fd5b80634be68d20146104455780634f1ef28614610464575f80fd5b8063192710811161029057806336cdd31b1161026b57806336cdd31b146103e85780633e63c50a1461040757806344ae9c5c14610426575f80fd5b8063192710811461038b5780632c7d67b7146103aa5780632e817ff0146103c9575f80fd5b80630b90dfc3116102c05780630b90dfc31461032c5780630d8e6e2c1461034b57806313801ffa1461036c575f80fd5b8063052896f1146102db578063059073431461030d575b5f80fd5b3480156102e6575f80fd5b506102fa6102f5366004613e5c565b610854565b6040519081526020015b60405180910390f35b348015610318575f80fd5b506102fa610327366004613e5c565b6108c1565b348015610337575f80fd5b506102fa610346366004613f2b565b610923565b348015610356575f80fd5b5061035f610970565b6040516103049190613fc2565b348015610377575f80fd5b506102fa610386366004613fd4565b6109eb565b348015610396575f80fd5b506102fa6103a5366004613e5c565b610a39565b3480156103b5575f80fd5b506102fa6103c4366004613e5c565b610a9b565b3480156103d4575f80fd5b506102fa6103e3366004614001565b610afd565b3480156103f3575f80fd5b506102fa610402366004613e5c565b610b5d565b348015610412575f80fd5b506102fa610421366004613e5c565b610bbf565b348015610431575f80fd5b506102fa610440366004613e5c565b610c21565b348015610450575f80fd5b506102fa61045f366004614065565b610c83565b61047761047236600461408f565b610ce4565b005b348015610484575f80fd5b506102fa610d03565b348015610498575f80fd5b505f805160206145f28339815191525b6040516001600160a01b039091168152602001610304565b3480156104cb575f80fd5b506102fa6104da366004613e5c565b610d31565b3480156104ea575f80fd5b506102fa6104f9366004613e5c565b610d93565b348015610509575f80fd5b506105115f81565b60405160ff9091168152602001610304565b34801561052e575f80fd5b506102fa61053d366004613e5c565b610df5565b34801561054d575f80fd5b50610477610e57565b348015610561575f80fd5b50610477610e6a565b348015610575575f80fd5b506102fa610584366004613e5c565b610eb7565b348015610594575f80fd5b506102fa6105a3366004613e5c565b610f19565b3480156105b3575f80fd5b506102fa6105c2366004613e5c565b610f7b565b3480156105d2575f80fd5b506104a8610fdd565b3480156105e6575f80fd5b506102fa6105f53660046140da565b611011565b348015610605575f80fd5b506102fa610614366004613e5c565b61108f565b348015610624575f80fd5b506102fa610633366004613e5c565b6110f1565b348015610643575f80fd5b506102fa610652366004613e5c565b611153565b348015610662575f80fd5b506102fa610671366004613fd4565b6111b5565b348015610681575f80fd5b507359aad6dc3c909aeed1916937cc310fbfbb118c8c6104a8565b3480156106a7575f80fd5b5061035f6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b3480156106ef575f80fd5b506102fa6106fe366004613f2b565b6111fa565b34801561070e575f80fd5b506102fa61071d3660046140f3565b611247565b34801561072d575f80fd5b506102fa61073c366004613e5c565b61129d565b34801561074c575f80fd5b506102fa61075b36600461411c565b6112ff565b34801561076b575f80fd5b506104a8611349565b34801561077f575f80fd5b506102fa61078e366004614065565b611371565b34801561079e575f80fd5b506102fa6107ad366004613e5c565b6113c8565b3480156107bd575f80fd5b506102fa6107cc366004613e5c565b61142a565b3480156107dc575f80fd5b506104776107eb36600461415e565b61148c565b3480156107fb575f80fd5b507374c085a069fafd4f264b5200847edb1ade82b3c06104a8565b348015610821575f80fd5b506102fa610830366004613e5c565b611511565b348015610840575f80fd5b506102fa61084f366004614065565b611573565b5f6108608484846115f8565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f07305072f94f1a0b168f31b63591b41f1cac5ba64014969410b6ceb606538ead906080015b60405180910390a29392505050565b5f6108cd848484611696565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f922410bc7a9d7326d875cdb9349f57cea73e4bb0b465d9d4675d5288ad8be22c906080016108b2565b5f61092f848484611729565b9050336001600160a01b03167f05b83108d217815a3573f69c82e0c26569d4c410780a147d494af52f6e008410858585856040516108b29493929190614177565b60606040518060400160405280600c81526020017f544648454578656375746f7200000000000000000000000000000000000000008152506109b15f611943565b6109bb6001611943565b6109c45f611943565b6040516020016109d794939291906141ac565b604051602081830303815290604052905090565b5f6109f5826119e0565b604080518481526020810183905291925033917f3dc0f0d4d45d9ff119f66df01d3e2d7a73493aae1eae33775b16b07789aafac391015b60405180910390a2919050565b5f610a45848484611a6a565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f3a0c714dad01280382b89beba9f8177783d66b696481415e929f1b02e328a541906080016108b2565b5f610aa7848484611b36565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907ffa4f6ace03749e024df9221c74694ef1e8c3066def6f40520e26e59708dd7056906080016108b2565b5f610b0a85858585611bc9565b9050336001600160a01b03167f0bb6dd385f84cff601e6e660e5e80ef8739b5935079f721f0cee8964491046ca8686868686604051610b4d959493929190614229565b60405180910390a2949350505050565b5f610b69848484611d25565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f92096614ef9cbda0318055bda767c14fb22206cc2cb5dcddf7b38eba7d6b2d29906080016108b2565b5f610bcb848484611dfe565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f46d5de07bfd63ec01cfb961ff5c91ce53698eb8bc8fe08079508daa3d5eadf89906080016108b2565b5f610c2d848484611e91565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fbf560b43a62ae4c9590fa5e029ed029e1710d290f9f8ece6f36108e4ed312e3e906080016108b2565b5f610c8e8383611f24565b604080518581526001600160f81b03198516602082015290810182905290915033907f2150548fbe9722e60d7871549c9870872d4d877ac58a4c1b8bc055f73446b523906060015b60405180910390a292915050565b610cec612196565b610cf58261224d565b610cff8282612255565b5050565b5f610d0c612329565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f610d3d848484612372565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f7ff8e1723ca2cb3d4048fe755a5a185dd3e34d5344276f68c124fd5d5571059a906080016108b2565b5f610d9f848484612405565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f0f80e720ac1dd11637d38469506987006a996cb767478e0ee4357bf1ce12bb19906080016108b2565b5f610e01848484612498565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f9cfba8fc76d24936bdc857fe511b746cbc99a2425215d19ec72275bbc5a8f0f4906080016108b2565b610e5f612564565b610e685f612596565b565b3380610e74611349565b6001600160a01b031614610eab5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610eb481612596565b50565b5f610ec38484846125ce565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f60a2b12ffdd4220bac10a5ed2cdd52d3ce4371b5262968193ab0e747db797c6a906080016108b2565b5f610f25848484612661565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f34c152a238a9c7a14b92def6b25511a8ac6cdf8f78dd60fbb476ca5fb1f0fd63906080016108b2565b5f610f878484846126f4565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f7f5c7ffaaf8e3391055dd5d55363f280b389861e2c9e4fb14ba861c803dd49ec906080016108b2565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f8061101b612787565b9050611027838261283b565b604080516001600160f81b0319861681526fffffffffffffffffffffffffffffffff198416602082015290810182905290925033907f50b413a0e3940d2f18ab88ad84adbaa5d72cc8d82e72efe97cd34c4ad3677f639060600160405180910390a250919050565b5f61109b848484612974565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fd8fd6601045cf1d0a0ab28a28526e5596d7cce32b35ad44de08d1e9969441aa2906080016108b2565b5f6110fd848484612a07565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f910b9089d67acb16e2833d86b8c100363cfae1bdcbd4fd228b45dde3dc4d0a9a906080016108b2565b5f61115f848484612a9a565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fad57799587312c4dec422afa3c1d721b88fb0d452cd5ed15a52c9b04f1225da3906080016108b2565b5f6111bf82612b2d565b604080518481526020810183905291925033917f2a54b047132067554c36d8d9aecc226f5518ab5af9a1e19b4e4d1cb401a56e909101610a2c565b5f611206848484612baf565b9050336001600160a01b03167f2e29e32638d6cfd749496bf7782fd284e2ce4782d0a0ea61a8f76ccfa0d06988858585856040516108b29493929190614177565b5f611253848484612d36565b60408051868152602081018690529081018490526060810182905290915033907f12e2bc1a29195780b5f5a0d2e773b1d343263d80b3cb9dcb051034bac5732b43906080016108b2565b5f6112a9848484612dc4565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907ffccefc29052f5ba36b6c1adc1432c30d32af11ff8796c6a5549da52fbd7d5de7906080016108b2565b5f61130a8383612e9d565b9050336001600160a01b03167f90e8a043ed9e0580c961b547a98e518f1cd95fc4feb95f716eb8d9ea27e18b02848484604051610cd69392919061426e565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00611001565b5f61137c8383612f5f565b604080518581526001600160f81b03198516602082015290810182905290915033907f96e65db2c6b1d30ffc84b4d5dc25fec064352ac89ff65a4463b4ed9bc4b6b70390606001610cd6565b5f6113d4848484613016565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f11cbf38d5137daf232c3d7dcc267c99b6e9a3c47f523eb64edce18490e26572a906080016108b2565b5f6114368484846130a9565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fa8c1a660b3b8efbeb115d6d6b0d7b2dafe6e16c58a60b54b04620ebfddd0ad68906080016108b2565b611494612564565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556114d8610fdd565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b5f61151d84848461313c565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f9d4485ee9ce87c267c409bdb9b696a82a89c995903092b84553de8edc2592625906080016108b2565b5f8061157d612787565b905061158a8484836131ce565b604080518681526001600160f81b0319861660208201526fffffffffffffffffffffffffffffffff1984168183015260608101839052905191935033917fc413adc84697f5254550ac298a61ed4e3ab3e6bc78d472f61e5322f974bc933b9181900360800190a25092915050565b5f61017e6116068582613331565b5f6116118660081c90565b60405163f1ec4e3d60e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063f1ec4e3d906044015f604051808303815f87803b158015611667575f80fd5b505af1158015611679573d5f803e3d5ffd5b5050505061168b600e8888845f613366565b979650505050505050565b5f61017e6116a48582613331565b5f6116af8660081c90565b60405163d52059c160e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063d52059c1906044015f604051808303815f87803b158015611705575f80fd5b505af1158015611717573d5f803e3d5ffd5b5050505061168b600a88888486613366565b5f610e006117378582613331565b5f6117428660081c90565b9050600160f81b80851690811461176c576040516309bbc1b360e31b815260040160405180910390fd5b604051633b470ee160e01b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290633b470ee1906044015f604051808303815f87803b1580156117c1575f80fd5b505af11580156117d3573d5f803e3d5ffd5b5050604051632fd514cd60e11b8152600481018a90523360248201527374c085a069fafd4f264b5200847edb1ade82b3c09250635faa299a9150604401602060405180830381865afa15801561182b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061184f919061429c565b6118755760405163268989cf60e11b815260048101889052336024820152604401610ea2565b6118808651836135c3565b600d8787837374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016118b0969594939291906142de565b60408051601f198184030181529190528051602090910120935061ffff1984166040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015611923575f80fd5b505af1158015611935573d5f803e3d5ffd5b505050505050509392505050565b60605f61194f83613661565b60010190505f8167ffffffffffffffff81111561196e5761196e613e8e565b6040519080825280601f01601f191660200182016040528015611998576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846119a257509392505050565b5f61017f6119ee8382613331565b5f6119f98460081c90565b6040516322f1ff5160e11b815260ff821660048201529091505f805160206145f2833981519152906345e3fea2906024015f604051808303815f87803b158015611a41575f80fd5b505af1158015611a53573d5f803e3d5ffd5b50505050611a62601585613743565b949350505050565b5f610fff611a788582613331565b5f611a838660081c90565b9050600160f81b8085169081148015611a9f575060088260ff16115b15611abd5760405163dac55bcd60e01b815260040160405180910390fd5b604051633b470ee160e01b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290633b470ee1906044015f604051808303815f87803b158015611b12575f80fd5b505af1158015611b24573d5f803e3d5ffd5b5050505061168b600d8888845f613366565b5f61017f611b448582613331565b5f611b4f8660081c90565b604051632f891e1b60e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290632f891e1b906044015f604051808303815f87803b158015611ba5575f80fd5b505af1158015611bb7573d5f803e3d5ffd5b5050505061168b600788888486613366565b604080516060810182527374c085a069fafd4f264b5200847edb1ade82b3c081526001600160a01b038516602082015233918101919091525f9081611c0e8760081c90565b905060f884901c60ff821614611c375760405163b968846160e01b815260040160405180910390fd5b604051634d52c10760e01b81527359aad6dc3c909aeed1916937cc310fbfbb118c8c90634d52c10790611c729085908b908a90600401614346565b6020604051808303815f875af1158015611c8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cb29190614388565b6040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015611d05575f80fd5b505af1158015611d17573d5f803e3d5ffd5b505050505050949350505050565b5f600160f81b80831614611d4c57604051634f224e5360e01b815260040160405180910390fd5b825f03611d6c576040516323d359a360e01b815260040160405180910390fd5b61017e611d798582613331565b5f611d848660081c90565b60405163293d01a360e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063a4f4068c906044015f604051808303815f87803b158015611dda575f80fd5b505af1158015611dec573d5f803e3d5ffd5b5050505061168b600388888486613366565b5f61017e611e0c8582613331565b5f611e178660081c90565b604051633941d74360e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063e5075d0c906044015f604051808303815f87803b158015611e6d575f80fd5b505af1158015611e7f573d5f803e3d5ffd5b5050505061168b600f8888845f613366565b5f61017e611e9f8582613331565b5f611eaa8660081c90565b604051636b053d1d60e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063d60a7a3a906044015f604051808303815f87803b158015611f00575f80fd5b505af1158015611f12573d5f803e3d5ffd5b5050505061168b600b88888486613366565b604051632fd514cd60e11b8152600481018390523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015611f7a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f9e919061429c565b611fc45760405163268989cf60e11b815260048101849052336024820152604401610ea2565b61017f611fd18482613331565b61017e600160f885901c1b81165f03611ffd5760405163636f233560e11b815260040160405180910390fd5b5f6120088660081c90565b9050847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168160f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036120715760405163b968846160e01b815260040160405180910390fd5b604051630abfbaad60e31b815260ff821660048201525f805160206145f2833981519152906355fdd568906024015f604051808303815f87803b1580156120b6575f80fd5b505af11580156120c8573d5f803e3d5ffd5b50505050601786867374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016120fa95949392919061439f565b60408051601f198184030181529190528051602090910120935061ffff19841660f086901c61ff0016176040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015612177575f80fd5b505af1158015612189573d5f803e3d5ffd5b5050505050505092915050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061222f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166122237f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614155b15610e685760405163703e46dd60e11b815260040160405180910390fd5b610eb4612564565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156122af575060408051601f3d908101601f191682019092526122ac91810190614388565b60015b6122d757604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610ea2565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461231a57604051632a87526960e21b815260048101829052602401610ea2565b61232483836138b5565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e685760405163703e46dd60e11b815260040160405180910390fd5b5f61017f6123808582613331565b5f61238b8660081c90565b6040516330cd786560e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063619af0ca906044015f604051808303815f87803b1580156123e1575f80fd5b505af11580156123f3573d5f803e3d5ffd5b5050505061168b600588888486613366565b5f61017e6124138582613331565b5f61241e8660081c90565b604051630b171ff760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630b171ff7906044015f604051808303815f87803b158015612474575f80fd5b505af1158015612486573d5f803e3d5ffd5b5050505061168b60108888845f613366565b5f610fff6124a68582613331565b5f6124b18660081c90565b9050600160f81b80851690811480156124cd575060088260ff16115b156124eb5760405163dac55bcd60e01b815260040160405180910390fd5b6040516308194a5360e41b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290638194a530906044015f604051808303815f87803b158015612540575f80fd5b505af1158015612552573d5f803e3d5ffd5b5050505061168b600c8888845f613366565b3361256d610fdd565b6001600160a01b031614610e685760405163118cdaa760e01b8152336004820152602401610ea2565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610cff8261390a565b5f61017e6125dc8582613331565b5f6125e78660081c90565b604051630bf4df3b60e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906317e9be76906044015f604051808303815f87803b15801561263d575f80fd5b505af115801561264f573d5f803e3d5ffd5b5050505061168b600288888486613366565b5f61017e61266f8582613331565b5f61267a8660081c90565b60405163061b95e560e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063186e5794906044015f604051808303815f87803b1580156126d0575f80fd5b505af11580156126e2573d5f803e3d5ffd5b5050505061168b600888888486613366565b5f61017e6127028582613331565b5f61270d8660081c90565b604051630144371760e41b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906314437170906044015f604051808303815f87803b158015612763575f80fd5b505af1158015612775573d5f803e3d5ffd5b5050505061168b600188888486613366565b7fa436a06f0efce5ea38c956a21e24202a59b3b746d48a23fb52b4a5bc33fe3e0080545f91907374c085a069fafd4f264b5200847edb1ade82b3c0466127ce6001436143fb565b60408051602081019590955260609390931b6bffffffffffffffffffffffff191692840192909252605483015240607482015242609482015260b40160408051601f1981840301815291905280516020909101208154909250815f6128328361440e565b91905055505090565b5f610f7f60f884901c6001811b821683036128695760405163636f233560e11b815260040160405180910390fd5b60405162d435d160e31b815260ff821660048201525f805160206145f2833981519152906306a1ae88906024015f604051808303815f87803b1580156128ad575f80fd5b505af11580156128bf573d5f803e3d5ffd5b50505050601a85856040516020016128d993929190614426565b60408051601f198184030181529190528051602090910120925061ffff198316600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015612956575f80fd5b505af1158015612968573d5f803e3d5ffd5b50505050505092915050565b5f61017e6129828582613331565b5f61298d8660081c90565b604051630b20432b60e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290632c810cac906044015f604051808303815f87803b1580156129e3575f80fd5b505af11580156129f5573d5f803e3d5ffd5b5050505061168b60118888845f613366565b5f61017e612a158582613331565b5f612a208660081c90565b60405163fced972760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063fced9727906044015f604051808303815f87803b158015612a76575f80fd5b505af1158015612a88573d5f803e3d5ffd5b5050505061168b601388888486613366565b5f61017e612aa88582613331565b5f612ab38660081c90565b60405163801ec40160e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063801ec401906044015f604051808303815f87803b158015612b09575f80fd5b505af1158015612b1b573d5f803e3d5ffd5b5050505061168b601288888486613366565b5f61017e612b3b8382613331565b5f612b468460081c90565b6040516333becb3b60e01b815260ff821660048201529091505f805160206145f2833981519152906333becb3b906024015f604051808303815f87803b158015612b8e575f80fd5b505af1158015612ba0573d5f803e3d5ffd5b50505050611a62601485613743565b5f610e00612bbd8582613331565b5f612bc88660081c90565b9050600160f81b808516908114612bf2576040516309bbc1b360e31b815260040160405180910390fd5b6040516308194a5360e41b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290638194a530906044015f604051808303815f87803b158015612c47575f80fd5b505af1158015612c59573d5f803e3d5ffd5b5050604051632fd514cd60e11b8152600481018a90523360248201527374c085a069fafd4f264b5200847edb1ade82b3c09250635faa299a9150604401602060405180830381865afa158015612cb1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cd5919061429c565b612cfb5760405163268989cf60e11b815260048101889052336024820152604401610ea2565b612d068651836135c3565b600c8787837374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016118b0969594939291906142de565b5f610fff612d448482613331565b5f612d4f8560081c90565b60405163e7b5afe360e01b815260ff821660048201529091505f805160206145f28339815191529063e7b5afe3906024015f604051808303815f87803b158015612d97575f80fd5b505af1158015612da9573d5f803e3d5ffd5b50505050612dba601987878761397a565b9695505050505050565b5f600160f81b80831614612deb57604051634f224e5360e01b815260040160405180910390fd5b825f03612e0b576040516323d359a360e01b815260040160405180910390fd5b61017e612e188582613331565b5f612e238660081c90565b604051634bf5249160e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906397ea4922906044015f604051808303815f87803b158015612e79575f80fd5b505af1158015612e8b573d5f803e3d5ffd5b5050505061168b600488888486613366565b5f610e0060f883901c6001811b82168303612ecb5760405163636f233560e11b815260040160405180910390fd5b6040516328c6831160e21b815260ff821660048201525f805160206145f28339815191529063a31a0c44906024015f604051808303815f87803b158015612f10575f80fd5b505af1158015612f22573d5f803e3d5ffd5b50505050612f318551826135c3565b601885857374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016128d9959493929190614462565b5f6101ff60f883901c6001811b82168303612f8d5760405163636f233560e11b815260040160405180910390fd5b6040516328c6831160e21b815260ff821660048201525f805160206145f28339815191529063a31a0c44906024015f604051808303815f87803b158015612fd2575f80fd5b505af1158015612fe4573d5f803e3d5ffd5b50505050601885857374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016128d995949392919061439f565b5f61017f6130248582613331565b5f61302f8660081c90565b604051630585a0d560e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630b0b41aa906044015f604051808303815f87803b158015613085575f80fd5b505af1158015613097573d5f803e3d5ffd5b5050505061168b600688888486613366565b5f61017e6130b78582613331565b5f6130c28660081c90565b604051630ae767b360e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630ae767b3906044015f604051808303815f87803b158015613118575f80fd5b505af115801561312a573d5f803e3d5ffd5b5050505061168b600988888486613366565b5f61017e61314a8582613331565b5f6131558660081c90565b604051639ec9108760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290639ec91087906044015f604051808303815f87803b1580156131ab575f80fd5b505af11580156131bd573d5f803e3d5ffd5b5050505061168b5f88888486613366565b5f61017e60f884901c6001811b821683036131fc5760405163636f233560e11b815260040160405180910390fd5b61320586613c92565b6132225760405163127473a160e11b815260040160405180910390fd5b604051633d5e922160e11b815260ff821660048201525f805160206145f283398151915290637abd2442906024015f604051808303815f87803b158015613267575f80fd5b505af1158015613279573d5f803e3d5ffd5b50505050601b86868660405160200161329594939291906144c3565b60408051601f198184030181529190528051602090910120925061ffff198316600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613312575f80fd5b505af1158015613324573d5f803e3d5ffd5b5050505050509392505050565b5f61333c8360081c90565b9050600160ff82161b82165f036123245760405163636f233560e11b815260040160405180910390fd5b604051632fd514cd60e11b8152600481018590523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa1580156133bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133e0919061429c565b6134065760405163268989cf60e11b815260048101869052336024820152604401610ea2565b6001600160f81b031983165f036134f857604051632fd514cd60e11b8152600481018590523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa15801561346b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061348f919061429c565b6134b55760405163268989cf60e11b815260048101859052336024820152604401610ea2565b5f6134c08560081c90565b90505f6134cd8760081c90565b90508160ff168160ff16146134f557604051631f3158c760e01b815260040160405180910390fd5b50505b858585857374c085a069fafd4f264b5200847edb1ade82b3c04660405160200161352796959493929190614507565b60408051601f198184030181529190528051602090910120905061ffff198116600883901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529091507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b1580156135a4575f80fd5b505af11580156135b6573d5f803e3d5ffd5b5050505095945050505050565b8060ff166009036135fb5781604014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b8060ff16600a036136335781608014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b8161010014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106136a9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106136d5576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106136f357662386f26fc10000830492506010015b6305f5e100831061370b576305f5e100830492506008015b612710831061371f57612710830492506004015b60648310613731576064830492506002015b600a831061373d576001015b92915050565b604051632fd514cd60e11b8152600481018290523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613799573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137bd919061429c565b6137e35760405163268989cf60e11b815260048101839052336024820152604401610ea2565b82827374c085a069fafd4f264b5200847edb1ade82b3c04660405160200161380e9493929190614557565b604051602081830303815290604052805190602001205f1c90505f6138338360081c90565b905061ffff198216600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529092507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613898575f80fd5b505af11580156138aa573d5f803e3d5ffd5b505050505092915050565b6138be82613cb1565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115613902576123248282613d27565b610cff613d99565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b604051632fd514cd60e11b8152600481018490523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa1580156139d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139f4919061429c565b613a1a5760405163268989cf60e11b815260048101859052336024820152604401610ea2565b604051632fd514cd60e11b8152600481018490523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613a6e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a92919061429c565b613ab85760405163268989cf60e11b815260048101849052336024820152604401610ea2565b604051632fd514cd60e11b8152600481018390523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613b0c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b30919061429c565b613b565760405163268989cf60e11b815260048101839052336024820152604401610ea2565b5f613b618560081c90565b90505f613b6e8560081c90565b90505f613b7b8560081c90565b905060ff831615613b9f5760405163636f233560e11b815260040160405180910390fd5b8060ff168260ff1614613bc557604051631f3158c760e01b815260040160405180910390fd5b878787877374c085a069fafd4f264b5200847edb1ade82b3c046604051602001613bf496959493929190614590565b60408051601f198184030181529190528051602090910120935061ffff198416600883901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613c71575f80fd5b505af1158015613c83573d5f803e3d5ffd5b50505050505050949350505050565b5f808211801561373d5750613ca86001836143fb565b82161592915050565b806001600160a01b03163b5f03613ce657604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610ea2565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b031684604051613d4391906145d6565b5f60405180830381855af49150503d805f8114613d7b576040519150601f19603f3d011682016040523d82523d5f602084013e613d80565b606091505b5091509150613d90858383613db8565b95945050505050565b3415610e685760405163b398979f60e01b815260040160405180910390fd5b606082613dcd57613dc882613e17565b613e10565b8151158015613de457506001600160a01b0384163b155b15613e0d57604051639996b31560e01b81526001600160a01b0385166004820152602401610ea2565b50805b9392505050565b805115613e275780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160f81b031981168114613e57575f80fd5b919050565b5f805f60608486031215613e6e575f80fd5b8335925060208401359150613e8560408501613e40565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112613eb1575f80fd5b813567ffffffffffffffff80821115613ecc57613ecc613e8e565b604051601f8301601f19908116603f01168101908282118183101715613ef457613ef4613e8e565b81604052838152866020858801011115613f0c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f60608486031215613f3d575f80fd5b83359250602084013567ffffffffffffffff811115613f5a575f80fd5b613f6686828701613ea2565b925050613e8560408501613e40565b5f5b83811015613f8f578181015183820152602001613f77565b50505f910152565b5f8151808452613fae816020860160208601613f75565b601f01601f19169290920160200192915050565b602081525f613e106020830184613f97565b5f60208284031215613fe4575f80fd5b5035919050565b80356001600160a01b0381168114613e57575f80fd5b5f805f8060808587031215614014575f80fd5b8435935061402460208601613feb565b9250604085013567ffffffffffffffff81111561403f575f80fd5b61404b87828801613ea2565b92505061405a60608601613e40565b905092959194509250565b5f8060408385031215614076575f80fd5b8235915061408660208401613e40565b90509250929050565b5f80604083850312156140a0575f80fd5b6140a983613feb565b9150602083013567ffffffffffffffff8111156140c4575f80fd5b6140d085828601613ea2565b9150509250929050565b5f602082840312156140ea575f80fd5b613e1082613e40565b5f805f60608486031215614105575f80fd5b505081359360208301359350604090920135919050565b5f806040838503121561412d575f80fd5b823567ffffffffffffffff811115614143575f80fd5b61414f85828601613ea2565b92505061408660208401613e40565b5f6020828403121561416e575f80fd5b613e1082613feb565b848152608060208201525f61418f6080830186613f97565b6001600160f81b0319949094166040830152506060015292915050565b5f85516141bd818460208a01613f75565b61103b60f11b90830190815285516141dc816002840160208a01613f75565b808201915050601760f91b8060028301528551614200816003850160208a01613f75565b6003920191820152835161421b816004840160208801613f75565b016004019695505050505050565b8581526001600160a01b038516602082015260a060408201525f61425060a0830186613f97565b6001600160f81b031994909416606083015250608001529392505050565b606081525f6142806060830186613f97565b6001600160f81b03199490941660208301525060400152919050565b5f602082840312156142ac575f80fd5b81518015158114613e10575f80fd5b601c81106142d757634e487b7160e01b5f52602160045260245ffd5b60f81b9052565b6142e881886142bb565b8560018201525f8551614302816021850160208a01613f75565b6001600160f81b0319959095166021929095019182019490945260609290921b6bffffffffffffffffffffffff191660228301526036820152605601949350505050565b5f6001600160a01b038086511683528060208701511660208401528060408701511660408401525083606083015260a06080830152613d9060a0830184613f97565b5f60208284031215614398575f80fd5b5051919050565b6143a981876142bb565b60018101949094526001600160f81b031992909216602184015260601b6bffffffffffffffffffffffff191660228301526036820152605601919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561373d5761373d6143e7565b5f6001820161441f5761441f6143e7565b5060010190565b61443081856142bb565b6001600160f81b03199290921660018301526fffffffffffffffffffffffffffffffff19166002820152601201919050565b61446c81876142bb565b5f8551614480816001850160208a01613f75565b6001600160f81b0319959095166001929095019182019490945260609290921b6bffffffffffffffffffffffff1916600283015260168201526036019392505050565b6144cd81866142bb565b60018101939093526001600160f81b03199190911660218301526fffffffffffffffffffffffffffffffff19166022820152603201919050565b61451181886142bb565b600181019590955260218501939093526001600160f81b031991909116604184015260601b6bffffffffffffffffffffffff191660428301526056820152607601919050565b61456181866142bb565b600181019390935260609190911b6bffffffffffffffffffffffff191660218301526035820152605501919050565b61459a81886142bb565b60018101959095526021850193909352604184019190915260601b6bffffffffffffffffffffffff191660618301526075820152609501919050565b5f82516145e7818460208701613f75565b919091019291505056fe0000000000000000000000002ea4b09a56bf59437c99293af54f8e39e11a68baa164736f6c6343000818000a", + "deployedBytecode": "0x6080604052600436106102d7575f3560e01c806389a4314b1161017b578063cb3b9407116100d1578063ec4057dc11610087578063f6859bdc11610062578063f6859bdc146107f0578063f953e42714610816578063fa33b7af14610835575f80fd5b8063ec4057dc14610793578063eee1833c146107b2578063f2fde38b146107d1575f80fd5b8063e0c5cbb3116100b7578063e0c5cbb314610741578063e30c397814610760578063e71746b814610774575f80fd5b8063cb3b940714610703578063e0c516ae14610722575f80fd5b8063a86e9de511610131578063a8c7c2c11161010c578063a8c7c2c114610676578063ad3cb1cc1461069c578063bc47139a146106e4575f80fd5b8063a86e9de514610619578063a87deac414610638578063a8b42a8914610657575f80fd5b80638da5cb5b116101615780638da5cb5b146105c7578063900d294e146105db5780639675211f146105fa575f80fd5b806389a4314b146105895780638c14cc21146105a8575f80fd5b80634be68d2011610230578063694daf72116101e6578063715018a6116101c1578063715018a61461054257806379ba509714610556578063816d57d31461056a575f80fd5b8063694daf72146104df5780636a8c8eb4146104fe5780636be3175814610523575f80fd5b806352d1902d1161021657806352d1902d14610479578063601303d11461048d578063666a3588146104c0575f80fd5b80634be68d20146104455780634f1ef28614610464575f80fd5b8063192710811161029057806336cdd31b1161026b57806336cdd31b146103e85780633e63c50a1461040757806344ae9c5c14610426575f80fd5b8063192710811461038b5780632c7d67b7146103aa5780632e817ff0146103c9575f80fd5b80630b90dfc3116102c05780630b90dfc31461032c5780630d8e6e2c1461034b57806313801ffa1461036c575f80fd5b8063052896f1146102db578063059073431461030d575b5f80fd5b3480156102e6575f80fd5b506102fa6102f5366004613e5c565b610854565b6040519081526020015b60405180910390f35b348015610318575f80fd5b506102fa610327366004613e5c565b6108c1565b348015610337575f80fd5b506102fa610346366004613f2b565b610923565b348015610356575f80fd5b5061035f610970565b6040516103049190613fc2565b348015610377575f80fd5b506102fa610386366004613fd4565b6109eb565b348015610396575f80fd5b506102fa6103a5366004613e5c565b610a39565b3480156103b5575f80fd5b506102fa6103c4366004613e5c565b610a9b565b3480156103d4575f80fd5b506102fa6103e3366004614001565b610afd565b3480156103f3575f80fd5b506102fa610402366004613e5c565b610b5d565b348015610412575f80fd5b506102fa610421366004613e5c565b610bbf565b348015610431575f80fd5b506102fa610440366004613e5c565b610c21565b348015610450575f80fd5b506102fa61045f366004614065565b610c83565b61047761047236600461408f565b610ce4565b005b348015610484575f80fd5b506102fa610d03565b348015610498575f80fd5b505f805160206145f28339815191525b6040516001600160a01b039091168152602001610304565b3480156104cb575f80fd5b506102fa6104da366004613e5c565b610d31565b3480156104ea575f80fd5b506102fa6104f9366004613e5c565b610d93565b348015610509575f80fd5b506105115f81565b60405160ff9091168152602001610304565b34801561052e575f80fd5b506102fa61053d366004613e5c565b610df5565b34801561054d575f80fd5b50610477610e57565b348015610561575f80fd5b50610477610e6a565b348015610575575f80fd5b506102fa610584366004613e5c565b610eb7565b348015610594575f80fd5b506102fa6105a3366004613e5c565b610f19565b3480156105b3575f80fd5b506102fa6105c2366004613e5c565b610f7b565b3480156105d2575f80fd5b506104a8610fdd565b3480156105e6575f80fd5b506102fa6105f53660046140da565b611011565b348015610605575f80fd5b506102fa610614366004613e5c565b61108f565b348015610624575f80fd5b506102fa610633366004613e5c565b6110f1565b348015610643575f80fd5b506102fa610652366004613e5c565b611153565b348015610662575f80fd5b506102fa610671366004613fd4565b6111b5565b348015610681575f80fd5b507359aad6dc3c909aeed1916937cc310fbfbb118c8c6104a8565b3480156106a7575f80fd5b5061035f6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b3480156106ef575f80fd5b506102fa6106fe366004613f2b565b6111fa565b34801561070e575f80fd5b506102fa61071d3660046140f3565b611247565b34801561072d575f80fd5b506102fa61073c366004613e5c565b61129d565b34801561074c575f80fd5b506102fa61075b36600461411c565b6112ff565b34801561076b575f80fd5b506104a8611349565b34801561077f575f80fd5b506102fa61078e366004614065565b611371565b34801561079e575f80fd5b506102fa6107ad366004613e5c565b6113c8565b3480156107bd575f80fd5b506102fa6107cc366004613e5c565b61142a565b3480156107dc575f80fd5b506104776107eb36600461415e565b61148c565b3480156107fb575f80fd5b507374c085a069fafd4f264b5200847edb1ade82b3c06104a8565b348015610821575f80fd5b506102fa610830366004613e5c565b611511565b348015610840575f80fd5b506102fa61084f366004614065565b611573565b5f6108608484846115f8565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f07305072f94f1a0b168f31b63591b41f1cac5ba64014969410b6ceb606538ead906080015b60405180910390a29392505050565b5f6108cd848484611696565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f922410bc7a9d7326d875cdb9349f57cea73e4bb0b465d9d4675d5288ad8be22c906080016108b2565b5f61092f848484611729565b9050336001600160a01b03167f05b83108d217815a3573f69c82e0c26569d4c410780a147d494af52f6e008410858585856040516108b29493929190614177565b60606040518060400160405280600c81526020017f544648454578656375746f7200000000000000000000000000000000000000008152506109b15f611943565b6109bb6001611943565b6109c45f611943565b6040516020016109d794939291906141ac565b604051602081830303815290604052905090565b5f6109f5826119e0565b604080518481526020810183905291925033917f3dc0f0d4d45d9ff119f66df01d3e2d7a73493aae1eae33775b16b07789aafac391015b60405180910390a2919050565b5f610a45848484611a6a565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f3a0c714dad01280382b89beba9f8177783d66b696481415e929f1b02e328a541906080016108b2565b5f610aa7848484611b36565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907ffa4f6ace03749e024df9221c74694ef1e8c3066def6f40520e26e59708dd7056906080016108b2565b5f610b0a85858585611bc9565b9050336001600160a01b03167f0bb6dd385f84cff601e6e660e5e80ef8739b5935079f721f0cee8964491046ca8686868686604051610b4d959493929190614229565b60405180910390a2949350505050565b5f610b69848484611d25565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f92096614ef9cbda0318055bda767c14fb22206cc2cb5dcddf7b38eba7d6b2d29906080016108b2565b5f610bcb848484611dfe565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f46d5de07bfd63ec01cfb961ff5c91ce53698eb8bc8fe08079508daa3d5eadf89906080016108b2565b5f610c2d848484611e91565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fbf560b43a62ae4c9590fa5e029ed029e1710d290f9f8ece6f36108e4ed312e3e906080016108b2565b5f610c8e8383611f24565b604080518581526001600160f81b03198516602082015290810182905290915033907f2150548fbe9722e60d7871549c9870872d4d877ac58a4c1b8bc055f73446b523906060015b60405180910390a292915050565b610cec612196565b610cf58261224d565b610cff8282612255565b5050565b5f610d0c612329565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f610d3d848484612372565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f7ff8e1723ca2cb3d4048fe755a5a185dd3e34d5344276f68c124fd5d5571059a906080016108b2565b5f610d9f848484612405565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f0f80e720ac1dd11637d38469506987006a996cb767478e0ee4357bf1ce12bb19906080016108b2565b5f610e01848484612498565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f9cfba8fc76d24936bdc857fe511b746cbc99a2425215d19ec72275bbc5a8f0f4906080016108b2565b610e5f612564565b610e685f612596565b565b3380610e74611349565b6001600160a01b031614610eab5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610eb481612596565b50565b5f610ec38484846125ce565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f60a2b12ffdd4220bac10a5ed2cdd52d3ce4371b5262968193ab0e747db797c6a906080016108b2565b5f610f25848484612661565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f34c152a238a9c7a14b92def6b25511a8ac6cdf8f78dd60fbb476ca5fb1f0fd63906080016108b2565b5f610f878484846126f4565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f7f5c7ffaaf8e3391055dd5d55363f280b389861e2c9e4fb14ba861c803dd49ec906080016108b2565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f8061101b612787565b9050611027838261283b565b604080516001600160f81b0319861681526fffffffffffffffffffffffffffffffff198416602082015290810182905290925033907f50b413a0e3940d2f18ab88ad84adbaa5d72cc8d82e72efe97cd34c4ad3677f639060600160405180910390a250919050565b5f61109b848484612974565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fd8fd6601045cf1d0a0ab28a28526e5596d7cce32b35ad44de08d1e9969441aa2906080016108b2565b5f6110fd848484612a07565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f910b9089d67acb16e2833d86b8c100363cfae1bdcbd4fd228b45dde3dc4d0a9a906080016108b2565b5f61115f848484612a9a565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fad57799587312c4dec422afa3c1d721b88fb0d452cd5ed15a52c9b04f1225da3906080016108b2565b5f6111bf82612b2d565b604080518481526020810183905291925033917f2a54b047132067554c36d8d9aecc226f5518ab5af9a1e19b4e4d1cb401a56e909101610a2c565b5f611206848484612baf565b9050336001600160a01b03167f2e29e32638d6cfd749496bf7782fd284e2ce4782d0a0ea61a8f76ccfa0d06988858585856040516108b29493929190614177565b5f611253848484612d36565b60408051868152602081018690529081018490526060810182905290915033907f12e2bc1a29195780b5f5a0d2e773b1d343263d80b3cb9dcb051034bac5732b43906080016108b2565b5f6112a9848484612dc4565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907ffccefc29052f5ba36b6c1adc1432c30d32af11ff8796c6a5549da52fbd7d5de7906080016108b2565b5f61130a8383612e9d565b9050336001600160a01b03167f90e8a043ed9e0580c961b547a98e518f1cd95fc4feb95f716eb8d9ea27e18b02848484604051610cd69392919061426e565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00611001565b5f61137c8383612f5f565b604080518581526001600160f81b03198516602082015290810182905290915033907f96e65db2c6b1d30ffc84b4d5dc25fec064352ac89ff65a4463b4ed9bc4b6b70390606001610cd6565b5f6113d4848484613016565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f11cbf38d5137daf232c3d7dcc267c99b6e9a3c47f523eb64edce18490e26572a906080016108b2565b5f6114368484846130a9565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907fa8c1a660b3b8efbeb115d6d6b0d7b2dafe6e16c58a60b54b04620ebfddd0ad68906080016108b2565b611494612564565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556114d8610fdd565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b5f61151d84848461313c565b60408051868152602081018690526001600160f81b03198516918101919091526060810182905290915033907f9d4485ee9ce87c267c409bdb9b696a82a89c995903092b84553de8edc2592625906080016108b2565b5f8061157d612787565b905061158a8484836131ce565b604080518681526001600160f81b0319861660208201526fffffffffffffffffffffffffffffffff1984168183015260608101839052905191935033917fc413adc84697f5254550ac298a61ed4e3ab3e6bc78d472f61e5322f974bc933b9181900360800190a25092915050565b5f61017e6116068582613331565b5f6116118660081c90565b60405163f1ec4e3d60e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063f1ec4e3d906044015f604051808303815f87803b158015611667575f80fd5b505af1158015611679573d5f803e3d5ffd5b5050505061168b600e8888845f613366565b979650505050505050565b5f61017e6116a48582613331565b5f6116af8660081c90565b60405163d52059c160e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063d52059c1906044015f604051808303815f87803b158015611705575f80fd5b505af1158015611717573d5f803e3d5ffd5b5050505061168b600a88888486613366565b5f610e006117378582613331565b5f6117428660081c90565b9050600160f81b80851690811461176c576040516309bbc1b360e31b815260040160405180910390fd5b604051633b470ee160e01b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290633b470ee1906044015f604051808303815f87803b1580156117c1575f80fd5b505af11580156117d3573d5f803e3d5ffd5b5050604051632fd514cd60e11b8152600481018a90523360248201527374c085a069fafd4f264b5200847edb1ade82b3c09250635faa299a9150604401602060405180830381865afa15801561182b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061184f919061429c565b6118755760405163268989cf60e11b815260048101889052336024820152604401610ea2565b6118808651836135c3565b600d8787837374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016118b0969594939291906142de565b60408051601f198184030181529190528051602090910120935061ffff1984166040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015611923575f80fd5b505af1158015611935573d5f803e3d5ffd5b505050505050509392505050565b60605f61194f83613661565b60010190505f8167ffffffffffffffff81111561196e5761196e613e8e565b6040519080825280601f01601f191660200182016040528015611998576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846119a257509392505050565b5f61017f6119ee8382613331565b5f6119f98460081c90565b6040516322f1ff5160e11b815260ff821660048201529091505f805160206145f2833981519152906345e3fea2906024015f604051808303815f87803b158015611a41575f80fd5b505af1158015611a53573d5f803e3d5ffd5b50505050611a62601585613743565b949350505050565b5f610fff611a788582613331565b5f611a838660081c90565b9050600160f81b8085169081148015611a9f575060088260ff16115b15611abd5760405163dac55bcd60e01b815260040160405180910390fd5b604051633b470ee160e01b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290633b470ee1906044015f604051808303815f87803b158015611b12575f80fd5b505af1158015611b24573d5f803e3d5ffd5b5050505061168b600d8888845f613366565b5f61017f611b448582613331565b5f611b4f8660081c90565b604051632f891e1b60e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290632f891e1b906044015f604051808303815f87803b158015611ba5575f80fd5b505af1158015611bb7573d5f803e3d5ffd5b5050505061168b600788888486613366565b604080516060810182527374c085a069fafd4f264b5200847edb1ade82b3c081526001600160a01b038516602082015233918101919091525f9081611c0e8760081c90565b905060f884901c60ff821614611c375760405163b968846160e01b815260040160405180910390fd5b604051634d52c10760e01b81527359aad6dc3c909aeed1916937cc310fbfbb118c8c90634d52c10790611c729085908b908a90600401614346565b6020604051808303815f875af1158015611c8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cb29190614388565b6040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015611d05575f80fd5b505af1158015611d17573d5f803e3d5ffd5b505050505050949350505050565b5f600160f81b80831614611d4c57604051634f224e5360e01b815260040160405180910390fd5b825f03611d6c576040516323d359a360e01b815260040160405180910390fd5b61017e611d798582613331565b5f611d848660081c90565b60405163293d01a360e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063a4f4068c906044015f604051808303815f87803b158015611dda575f80fd5b505af1158015611dec573d5f803e3d5ffd5b5050505061168b600388888486613366565b5f61017e611e0c8582613331565b5f611e178660081c90565b604051633941d74360e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063e5075d0c906044015f604051808303815f87803b158015611e6d575f80fd5b505af1158015611e7f573d5f803e3d5ffd5b5050505061168b600f8888845f613366565b5f61017e611e9f8582613331565b5f611eaa8660081c90565b604051636b053d1d60e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063d60a7a3a906044015f604051808303815f87803b158015611f00575f80fd5b505af1158015611f12573d5f803e3d5ffd5b5050505061168b600b88888486613366565b604051632fd514cd60e11b8152600481018390523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015611f7a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f9e919061429c565b611fc45760405163268989cf60e11b815260048101849052336024820152604401610ea2565b61017f611fd18482613331565b61017e600160f885901c1b81165f03611ffd5760405163636f233560e11b815260040160405180910390fd5b5f6120088660081c90565b9050847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168160f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036120715760405163b968846160e01b815260040160405180910390fd5b604051630abfbaad60e31b815260ff821660048201525f805160206145f2833981519152906355fdd568906024015f604051808303815f87803b1580156120b6575f80fd5b505af11580156120c8573d5f803e3d5ffd5b50505050601786867374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016120fa95949392919061439f565b60408051601f198184030181529190528051602090910120935061ffff19841660f086901c61ff0016176040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015612177575f80fd5b505af1158015612189573d5f803e3d5ffd5b5050505050505092915050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061222f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166122237f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614155b15610e685760405163703e46dd60e11b815260040160405180910390fd5b610eb4612564565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156122af575060408051601f3d908101601f191682019092526122ac91810190614388565b60015b6122d757604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610ea2565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc811461231a57604051632a87526960e21b815260048101829052602401610ea2565b61232483836138b5565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e685760405163703e46dd60e11b815260040160405180910390fd5b5f61017f6123808582613331565b5f61238b8660081c90565b6040516330cd786560e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063619af0ca906044015f604051808303815f87803b1580156123e1575f80fd5b505af11580156123f3573d5f803e3d5ffd5b5050505061168b600588888486613366565b5f61017e6124138582613331565b5f61241e8660081c90565b604051630b171ff760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630b171ff7906044015f604051808303815f87803b158015612474575f80fd5b505af1158015612486573d5f803e3d5ffd5b5050505061168b60108888845f613366565b5f610fff6124a68582613331565b5f6124b18660081c90565b9050600160f81b80851690811480156124cd575060088260ff16115b156124eb5760405163dac55bcd60e01b815260040160405180910390fd5b6040516308194a5360e41b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290638194a530906044015f604051808303815f87803b158015612540575f80fd5b505af1158015612552573d5f803e3d5ffd5b5050505061168b600c8888845f613366565b3361256d610fdd565b6001600160a01b031614610e685760405163118cdaa760e01b8152336004820152602401610ea2565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610cff8261390a565b5f61017e6125dc8582613331565b5f6125e78660081c90565b604051630bf4df3b60e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906317e9be76906044015f604051808303815f87803b15801561263d575f80fd5b505af115801561264f573d5f803e3d5ffd5b5050505061168b600288888486613366565b5f61017e61266f8582613331565b5f61267a8660081c90565b60405163061b95e560e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063186e5794906044015f604051808303815f87803b1580156126d0575f80fd5b505af11580156126e2573d5f803e3d5ffd5b5050505061168b600888888486613366565b5f61017e6127028582613331565b5f61270d8660081c90565b604051630144371760e41b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906314437170906044015f604051808303815f87803b158015612763575f80fd5b505af1158015612775573d5f803e3d5ffd5b5050505061168b600188888486613366565b7fa436a06f0efce5ea38c956a21e24202a59b3b746d48a23fb52b4a5bc33fe3e0080545f91907374c085a069fafd4f264b5200847edb1ade82b3c0466127ce6001436143fb565b60408051602081019590955260609390931b6bffffffffffffffffffffffff191692840192909252605483015240607482015242609482015260b40160408051601f1981840301815291905280516020909101208154909250815f6128328361440e565b91905055505090565b5f610f7f60f884901c6001811b821683036128695760405163636f233560e11b815260040160405180910390fd5b60405162d435d160e31b815260ff821660048201525f805160206145f2833981519152906306a1ae88906024015f604051808303815f87803b1580156128ad575f80fd5b505af11580156128bf573d5f803e3d5ffd5b50505050601a85856040516020016128d993929190614426565b60408051601f198184030181529190528051602090910120925061ffff198316600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015612956575f80fd5b505af1158015612968573d5f803e3d5ffd5b50505050505092915050565b5f61017e6129828582613331565b5f61298d8660081c90565b604051630b20432b60e21b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290632c810cac906044015f604051808303815f87803b1580156129e3575f80fd5b505af11580156129f5573d5f803e3d5ffd5b5050505061168b60118888845f613366565b5f61017e612a158582613331565b5f612a208660081c90565b60405163fced972760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063fced9727906044015f604051808303815f87803b158015612a76575f80fd5b505af1158015612a88573d5f803e3d5ffd5b5050505061168b601388888486613366565b5f61017e612aa88582613331565b5f612ab38660081c90565b60405163801ec40160e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f28339815191529063801ec401906044015f604051808303815f87803b158015612b09575f80fd5b505af1158015612b1b573d5f803e3d5ffd5b5050505061168b601288888486613366565b5f61017e612b3b8382613331565b5f612b468460081c90565b6040516333becb3b60e01b815260ff821660048201529091505f805160206145f2833981519152906333becb3b906024015f604051808303815f87803b158015612b8e575f80fd5b505af1158015612ba0573d5f803e3d5ffd5b50505050611a62601485613743565b5f610e00612bbd8582613331565b5f612bc88660081c90565b9050600160f81b808516908114612bf2576040516309bbc1b360e31b815260040160405180910390fd5b6040516308194a5360e41b815260ff831660048201526001600160f81b0319821660248201525f805160206145f283398151915290638194a530906044015f604051808303815f87803b158015612c47575f80fd5b505af1158015612c59573d5f803e3d5ffd5b5050604051632fd514cd60e11b8152600481018a90523360248201527374c085a069fafd4f264b5200847edb1ade82b3c09250635faa299a9150604401602060405180830381865afa158015612cb1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cd5919061429c565b612cfb5760405163268989cf60e11b815260048101889052336024820152604401610ea2565b612d068651836135c3565b600c8787837374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016118b0969594939291906142de565b5f610fff612d448482613331565b5f612d4f8560081c90565b60405163e7b5afe360e01b815260ff821660048201529091505f805160206145f28339815191529063e7b5afe3906024015f604051808303815f87803b158015612d97575f80fd5b505af1158015612da9573d5f803e3d5ffd5b50505050612dba601987878761397a565b9695505050505050565b5f600160f81b80831614612deb57604051634f224e5360e01b815260040160405180910390fd5b825f03612e0b576040516323d359a360e01b815260040160405180910390fd5b61017e612e188582613331565b5f612e238660081c90565b604051634bf5249160e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f2833981519152906397ea4922906044015f604051808303815f87803b158015612e79575f80fd5b505af1158015612e8b573d5f803e3d5ffd5b5050505061168b600488888486613366565b5f610e0060f883901c6001811b82168303612ecb5760405163636f233560e11b815260040160405180910390fd5b6040516328c6831160e21b815260ff821660048201525f805160206145f28339815191529063a31a0c44906024015f604051808303815f87803b158015612f10575f80fd5b505af1158015612f22573d5f803e3d5ffd5b50505050612f318551826135c3565b601885857374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016128d9959493929190614462565b5f6101ff60f883901c6001811b82168303612f8d5760405163636f233560e11b815260040160405180910390fd5b6040516328c6831160e21b815260ff821660048201525f805160206145f28339815191529063a31a0c44906024015f604051808303815f87803b158015612fd2575f80fd5b505af1158015612fe4573d5f803e3d5ffd5b50505050601885857374c085a069fafd4f264b5200847edb1ade82b3c0466040516020016128d995949392919061439f565b5f61017f6130248582613331565b5f61302f8660081c90565b604051630585a0d560e11b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630b0b41aa906044015f604051808303815f87803b158015613085575f80fd5b505af1158015613097573d5f803e3d5ffd5b5050505061168b600688888486613366565b5f61017e6130b78582613331565b5f6130c28660081c90565b604051630ae767b360e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290630ae767b3906044015f604051808303815f87803b158015613118575f80fd5b505af115801561312a573d5f803e3d5ffd5b5050505061168b600988888486613366565b5f61017e61314a8582613331565b5f6131558660081c90565b604051639ec9108760e01b815260ff82166004820152600160f81b8616602482018190529192505f805160206145f283398151915290639ec91087906044015f604051808303815f87803b1580156131ab575f80fd5b505af11580156131bd573d5f803e3d5ffd5b5050505061168b5f88888486613366565b5f61017e60f884901c6001811b821683036131fc5760405163636f233560e11b815260040160405180910390fd5b61320586613c92565b6132225760405163127473a160e11b815260040160405180910390fd5b604051633d5e922160e11b815260ff821660048201525f805160206145f283398151915290637abd2442906024015f604051808303815f87803b158015613267575f80fd5b505af1158015613279573d5f803e3d5ffd5b50505050601b86868660405160200161329594939291906144c3565b60408051601f198184030181529190528051602090910120925061ffff198316600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529093507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613312575f80fd5b505af1158015613324573d5f803e3d5ffd5b5050505050509392505050565b5f61333c8360081c90565b9050600160ff82161b82165f036123245760405163636f233560e11b815260040160405180910390fd5b604051632fd514cd60e11b8152600481018590523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa1580156133bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133e0919061429c565b6134065760405163268989cf60e11b815260048101869052336024820152604401610ea2565b6001600160f81b031983165f036134f857604051632fd514cd60e11b8152600481018590523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa15801561346b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061348f919061429c565b6134b55760405163268989cf60e11b815260048101859052336024820152604401610ea2565b5f6134c08560081c90565b90505f6134cd8760081c90565b90508160ff168160ff16146134f557604051631f3158c760e01b815260040160405180910390fd5b50505b858585857374c085a069fafd4f264b5200847edb1ade82b3c04660405160200161352796959493929190614507565b60408051601f198184030181529190528051602090910120905061ffff198116600883901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529091507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b1580156135a4575f80fd5b505af11580156135b6573d5f803e3d5ffd5b5050505095945050505050565b8060ff166009036135fb5781604014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b8060ff16600a036136335781608014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b8161010014610cff5760405163b30c0c5760e01b815260ff8216600482015260248101839052604401610ea2565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106136a9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106136d5576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106136f357662386f26fc10000830492506010015b6305f5e100831061370b576305f5e100830492506008015b612710831061371f57612710830492506004015b60648310613731576064830492506002015b600a831061373d576001015b92915050565b604051632fd514cd60e11b8152600481018290523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613799573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137bd919061429c565b6137e35760405163268989cf60e11b815260048101839052336024820152604401610ea2565b82827374c085a069fafd4f264b5200847edb1ade82b3c04660405160200161380e9493929190614557565b604051602081830303815290604052805190602001205f1c90505f6138338360081c90565b905061ffff198216600882901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529092507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613898575f80fd5b505af11580156138aa573d5f803e3d5ffd5b505050505092915050565b6138be82613cb1565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115613902576123248282613d27565b610cff613d99565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b604051632fd514cd60e11b8152600481018490523360248201525f907374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa1580156139d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139f4919061429c565b613a1a5760405163268989cf60e11b815260048101859052336024820152604401610ea2565b604051632fd514cd60e11b8152600481018490523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613a6e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a92919061429c565b613ab85760405163268989cf60e11b815260048101849052336024820152604401610ea2565b604051632fd514cd60e11b8152600481018390523360248201527374c085a069fafd4f264b5200847edb1ade82b3c090635faa299a90604401602060405180830381865afa158015613b0c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b30919061429c565b613b565760405163268989cf60e11b815260048101839052336024820152604401610ea2565b5f613b618560081c90565b90505f613b6e8560081c90565b90505f613b7b8560081c90565b905060ff831615613b9f5760405163636f233560e11b815260040160405180910390fd5b8060ff168260ff1614613bc557604051631f3158c760e01b815260040160405180910390fd5b878787877374c085a069fafd4f264b5200847edb1ade82b3c046604051602001613bf496959493929190614590565b60408051601f198184030181529190528051602090910120935061ffff198416600883901b61ff0016176040516346ce4e4960e11b8152600481018290523360248201529094507374c085a069fafd4f264b5200847edb1ade82b3c090638d9c9c92906044015f604051808303815f87803b158015613c71575f80fd5b505af1158015613c83573d5f803e3d5ffd5b50505050505050949350505050565b5f808211801561373d5750613ca86001836143fb565b82161592915050565b806001600160a01b03163b5f03613ce657604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610ea2565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b031684604051613d4391906145d6565b5f60405180830381855af49150503d805f8114613d7b576040519150601f19603f3d011682016040523d82523d5f602084013e613d80565b606091505b5091509150613d90858383613db8565b95945050505050565b3415610e685760405163b398979f60e01b815260040160405180910390fd5b606082613dcd57613dc882613e17565b613e10565b8151158015613de457506001600160a01b0384163b155b15613e0d57604051639996b31560e01b81526001600160a01b0385166004820152602401610ea2565b50805b9392505050565b805115613e275780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160f81b031981168114613e57575f80fd5b919050565b5f805f60608486031215613e6e575f80fd5b8335925060208401359150613e8560408501613e40565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112613eb1575f80fd5b813567ffffffffffffffff80821115613ecc57613ecc613e8e565b604051601f8301601f19908116603f01168101908282118183101715613ef457613ef4613e8e565b81604052838152866020858801011115613f0c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f60608486031215613f3d575f80fd5b83359250602084013567ffffffffffffffff811115613f5a575f80fd5b613f6686828701613ea2565b925050613e8560408501613e40565b5f5b83811015613f8f578181015183820152602001613f77565b50505f910152565b5f8151808452613fae816020860160208601613f75565b601f01601f19169290920160200192915050565b602081525f613e106020830184613f97565b5f60208284031215613fe4575f80fd5b5035919050565b80356001600160a01b0381168114613e57575f80fd5b5f805f8060808587031215614014575f80fd5b8435935061402460208601613feb565b9250604085013567ffffffffffffffff81111561403f575f80fd5b61404b87828801613ea2565b92505061405a60608601613e40565b905092959194509250565b5f8060408385031215614076575f80fd5b8235915061408660208401613e40565b90509250929050565b5f80604083850312156140a0575f80fd5b6140a983613feb565b9150602083013567ffffffffffffffff8111156140c4575f80fd5b6140d085828601613ea2565b9150509250929050565b5f602082840312156140ea575f80fd5b613e1082613e40565b5f805f60608486031215614105575f80fd5b505081359360208301359350604090920135919050565b5f806040838503121561412d575f80fd5b823567ffffffffffffffff811115614143575f80fd5b61414f85828601613ea2565b92505061408660208401613e40565b5f6020828403121561416e575f80fd5b613e1082613feb565b848152608060208201525f61418f6080830186613f97565b6001600160f81b0319949094166040830152506060015292915050565b5f85516141bd818460208a01613f75565b61103b60f11b90830190815285516141dc816002840160208a01613f75565b808201915050601760f91b8060028301528551614200816003850160208a01613f75565b6003920191820152835161421b816004840160208801613f75565b016004019695505050505050565b8581526001600160a01b038516602082015260a060408201525f61425060a0830186613f97565b6001600160f81b031994909416606083015250608001529392505050565b606081525f6142806060830186613f97565b6001600160f81b03199490941660208301525060400152919050565b5f602082840312156142ac575f80fd5b81518015158114613e10575f80fd5b601c81106142d757634e487b7160e01b5f52602160045260245ffd5b60f81b9052565b6142e881886142bb565b8560018201525f8551614302816021850160208a01613f75565b6001600160f81b0319959095166021929095019182019490945260609290921b6bffffffffffffffffffffffff191660228301526036820152605601949350505050565b5f6001600160a01b038086511683528060208701511660208401528060408701511660408401525083606083015260a06080830152613d9060a0830184613f97565b5f60208284031215614398575f80fd5b5051919050565b6143a981876142bb565b60018101949094526001600160f81b031992909216602184015260601b6bffffffffffffffffffffffff191660228301526036820152605601919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561373d5761373d6143e7565b5f6001820161441f5761441f6143e7565b5060010190565b61443081856142bb565b6001600160f81b03199290921660018301526fffffffffffffffffffffffffffffffff19166002820152601201919050565b61446c81876142bb565b5f8551614480816001850160208a01613f75565b6001600160f81b0319959095166001929095019182019490945260609290921b6bffffffffffffffffffffffff1916600283015260168201526036019392505050565b6144cd81866142bb565b60018101939093526001600160f81b03199190911660218301526fffffffffffffffffffffffffffffffff19166022820152603201919050565b61451181886142bb565b600181019590955260218501939093526001600160f81b031991909116604184015260601b6bffffffffffffffffffffffff191660428301526056820152607601919050565b61456181866142bb565b600181019390935260609190911b6bffffffffffffffffffffffff191660218301526035820152605501919050565b61459a81886142bb565b60018101959095526021850193909352604184019190915260601b6bffffffffffffffffffffffff191660618301526075820152609501919050565b5f82516145e7818460208701613f75565b919091019291505056fe0000000000000000000000002ea4b09a56bf59437c99293af54f8e39e11a68baa164736f6c6343000818000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/fhevm-engine/listener/src/contracts/mod.rs b/fhevm-engine/listener/src/contracts/mod.rs new file mode 100644 index 00000000..2c064a8e --- /dev/null +++ b/fhevm-engine/listener/src/contracts/mod.rs @@ -0,0 +1,20 @@ +use alloy::sol; + +#[allow(unused_imports)] // required for accessing ::COUNT +use alloy_sol_types::SolEventInterface; + +sol!( + #[allow(missing_docs)] + #[sol(rpc)] + #[derive(Debug, serde::Serialize, serde::Deserialize)] + AclContract, + "src/contracts/ACL.json.abi" +); + +sol!( + #[allow(missing_docs)] + #[sol(rpc)] + #[derive(Debug, serde::Serialize, serde::Deserialize)] + TfheContract, + "src/contracts/TFHEExecutor.json.abi" +); diff --git a/fhevm-engine/listener/src/lib.rs b/fhevm-engine/listener/src/lib.rs new file mode 100644 index 00000000..3f152f8b --- /dev/null +++ b/fhevm-engine/listener/src/lib.rs @@ -0,0 +1 @@ +pub mod contracts;