diff --git a/crates/evm-helpers/src/contracts.rs b/crates/evm-helpers/src/contracts.rs index 26dc174910..0546acaa45 100644 --- a/crates/evm-helpers/src/contracts.rs +++ b/crates/evm-helpers/src/contracts.rs @@ -127,7 +127,7 @@ sol! { function request(E3RequestParams calldata requestParams) external returns (uint256 e3Id, E3 memory e3); function enableE3Program(address e3Program) public returns (bool success); function publishCiphertextOutput(uint256 e3Id, bytes calldata ciphertextOutput, bytes calldata proof) external returns (bool success); - function publishPlaintextOutput(uint256 e3Id, bytes calldata data, bytes calldata proof) external returns (bool success); + function publishPlaintextOutput(uint256 e3Id, bytes calldata data, bytes calldata proof, bytes calldata foldProof) external returns (bool success); function getE3(uint256 e3Id) external view returns (E3 memory e3); function getE3Quote(E3RequestParams memory request) external view returns (uint256 fee); function getE3Stage(uint256 e3Id) external view returns (E3Stage stage); @@ -207,6 +207,7 @@ pub trait EnclaveWrite { e3_id: U256, data: Bytes, proof: Bytes, + fold_proof: Bytes, ) -> Result; } @@ -499,6 +500,7 @@ impl EnclaveWrite for EnclaveContract { e3_id: U256, data: Bytes, proof: Bytes, + fold_proof: Bytes, ) -> Result { let _guard = NONCE_LOCK.lock().await; let wallet_addr = self @@ -508,7 +510,7 @@ impl EnclaveWrite for EnclaveContract { let contract = Enclave::new(self.contract_address, &self.provider); let builder = contract - .publishPlaintextOutput(e3_id, data, proof) + .publishPlaintextOutput(e3_id, data, proof, fold_proof) .nonce(nonce); let receipt = builder.send().await?.get_receipt().await?; diff --git a/crates/evm/src/ciphernode_registry_sol.rs b/crates/evm/src/ciphernode_registry_sol.rs index 2ada5ef6ad..63b4fa435c 100644 --- a/crates/evm/src/ciphernode_registry_sol.rs +++ b/crates/evm/src/ciphernode_registry_sol.rs @@ -449,6 +449,7 @@ impl Handler, public_key: ArcBytes, pk_aggregation_proof: Option<&Proof>, + dkg_aggregated_proof: Option<&Proof>, ) -> Result { let e3_id_u256: U256 = e3_id.try_into()?; let public_key_bytes = Bytes::from(public_key.extract_bytes()); @@ -552,6 +554,10 @@ pub async fn publish_committee_to_registry encode_zk_proof(p)?, + None => Bytes::new(), + }; let nodes_vec: Vec
= nodes .into_iter() @@ -563,6 +569,7 @@ pub async fn publish_committee_to_registry Handler( e3_id: E3id, decrypted_output: Vec, aggregation_proof: Option<&Proof>, + c6_fold_proof: Option<&Proof>, ) -> Result { let e3_id: U256 = e3_id.try_into()?; @@ -234,10 +236,13 @@ async fn publish_plaintext_output( .pending() .await?; - let proof = aggregation_proof - .map(encode_zk_proof) - .transpose()? - .ok_or_else(|| anyhow::anyhow!("C7 proof missing or invalid"))?; + let proof = encode_zk_proof( + aggregation_proof.ok_or_else(|| anyhow::anyhow!("C7 proof missing or invalid"))?, + )?; + let fold_proof: Bytes = match c6_fold_proof { + Some(p) => encode_zk_proof(p)?, + None => Bytes::new(), + }; send_tx_with_retry( "publishPlaintextOutput", @@ -245,12 +250,13 @@ async fn publish_plaintext_output( || { info!("publishPlaintextOutput() e3_id={:?}", e3_id); let decrypted_output = Bytes::from(decrypted_output.clone()); + let fold_proof = fold_proof.clone(); let proof = proof.clone(); let contract = IEnclave::new(contract_address, provider.provider()); async move { let builder = contract - .publishPlaintextOutput(e3_id, decrypted_output, proof) + .publishPlaintextOutput(e3_id, decrypted_output, proof, fold_proof) .nonce(current_nonce); let receipt = builder.send().await?.get_receipt().await?; Ok(receipt) diff --git a/crates/evm/src/helpers.rs b/crates/evm/src/helpers.rs index 82005b18a6..8887295af4 100644 --- a/crates/evm/src/helpers.rs +++ b/crates/evm/src/helpers.rs @@ -320,8 +320,7 @@ mod tests { use e3_events::{CircuitName, Proof}; use e3_utils::ArcBytes; - /// Verifies encode_zk_proof produces ABI that matches BfvPkVerifier/BfvDecryptionVerifier: - /// abi.decode(proof, (bytes, bytes32[])) + /// Verifies encode_zk_proof produces ABI: abi.decode(proof, (bytes, bytes32[])) #[test] fn test_encode_zk_proof_abi_format() { let raw_proof = vec![1u8, 2, 3, 4, 5]; diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index bbb720bc06..72784717b8 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -4,22 +4,22 @@ chains: contracts: e3_program: address: "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00" - deploy_block: 31 + deploy_block: 30 enclave: address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - deploy_block: 13 + deploy_block: 12 ciphernode_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 9 + deploy_block: 8 bonding_registry: address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - deploy_block: 10 + deploy_block: 9 slashing_manager: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - deploy_block: 8 + deploy_block: 7 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - deploy_block: 4 + deploy_block: 3 program: dev: true # risc0: diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index f20d36aecf..0335eac42e 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -151,21 +151,21 @@ }, "localhost": { "PoseidonT3": { - "blockNumber": 3, + "blockNumber": 2, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 4, + "blockNumber": 3, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 5, + "blockNumber": 4, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { @@ -174,14 +174,14 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 7, + "blockNumber": 6, "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 8, + "blockNumber": 7, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "CiphernodeRegistryOwnable": { @@ -196,7 +196,7 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 9, + "blockNumber": 8, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "BondingRegistry": { @@ -218,7 +218,7 @@ "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 10, + "blockNumber": 9, "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { @@ -241,7 +241,7 @@ "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 13, + "blockNumber": 12, "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "E3RefundManager": { @@ -257,60 +257,60 @@ "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, - "blockNumber": 15, + "blockNumber": 14, "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, "MockComputeProvider": { - "blockNumber": 17, + "blockNumber": 16, "address": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E" }, "MockDecryptionVerifier": { - "blockNumber": 18, + "blockNumber": 17, "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690" }, "MockPkVerifier": { - "blockNumber": 19, + "blockNumber": 18, "address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB" }, "MockE3Program": { - "blockNumber": 20, + "blockNumber": 19, "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" }, "ZKTranscriptLib": { - "blockNumber": 22, + "blockNumber": 21, "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" }, "RecursiveAggregationFoldVerifier": { - "blockNumber": 23, + "blockNumber": 22, "address": "0x851356ae760d987E095750cCeb3bC6014560891C" }, "ThresholdDecryptedSharesAggregationVerifier": { - "blockNumber": 24, + "blockNumber": 23, "address": "0xf5059a5D33d5853360D16C683c16e67980206f36" }, "ThresholdPkAggregationVerifier": { - "blockNumber": 25, + "blockNumber": 24, "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" }, "BfvDecryptionVerifier": { - "blockNumber": 26, + "blockNumber": 25, "address": "0x998abeb3E57409262aE5b751f60747921B33613E" }, "BfvPkVerifier": { - "blockNumber": 28, + "blockNumber": 27, "address": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528" }, "MockRISC0Verifier": { "address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF", - "blockNumber": 30 + "blockNumber": 29 }, "HonkVerifier": { "address": "0x9d4454B023096f34B160D6B654540c56A1F81688", - "blockNumber": 31 + "blockNumber": 30 }, "CRISPProgram": { "address": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00", - "blockNumber": 31, + "blockNumber": 30, "constructorArgs": { "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", "verifierAddress": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF", @@ -320,7 +320,7 @@ }, "MockVotingToken": { "address": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D", - "blockNumber": 33 + "blockNumber": 32 } } } \ No newline at end of file diff --git a/examples/CRISP/server/src/cli/commands.rs b/examples/CRISP/server/src/cli/commands.rs index 3cb5613c37..a21ede01f4 100644 --- a/examples/CRISP/server/src/cli/commands.rs +++ b/examples/CRISP/server/src/cli/commands.rs @@ -311,6 +311,7 @@ pub async fn decrypt_and_publish_result( U256::from(input_crisp_id), Bytes::from(votes.to_be_bytes()), proof, + Bytes::new(), ) .await?; info!("Vote broadcast. TxHash: {:?}", res.transaction_hash); diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index be758b5471..9db1085ab1 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -1772,6 +1772,11 @@ "internalType": "bytes", "name": "proof", "type": "bytes" + }, + { + "internalType": "bytes", + "name": "foldProof", + "type": "bytes" } ], "name": "publishPlaintextOutput", @@ -2145,11 +2150,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b614949806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c80638e5ce3ad11610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b80639c8570c8116101315780639c8570c814610618578063ac3d2f421461062b578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b80638e5ce3ad1461058157806390173a41146105945780639117173c146105a957806392312386146105bc578063929a8faf146105cf57806399c6679d146105f0575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b5780637edcd7ab1461052e57806381476ec21461054157806385814243146105545780638da5cb5b146105675780638dcdd86b1461056f575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b31565b6107df565b005b6102da6102ea366004613be1565b610945565b6103176102fd366004613bfc565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c20565b60405180910390f35b61031761033b366004613bfc565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c47565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be1565b610a2d565b6102da61039e366004613c6f565b610ad2565b6103c56103b1366004613bfc565b5f908152600f602052604090205460ff1690565b6040516103249190613cb1565b6103e56103e0366004613bfc565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613cfd565b61041261040d366004613bfc565b610d10565b6040516103249190613eed565b61043e61042d366004613bfc565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613eff565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613bfc565b61100d565b6102da6104ab366004613be1565b61109c565b6104c36104be366004613f38565b61112f565b604051610324929190613f6f565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f87565b61194e565b6102da610516366004613fb8565b6119e6565b6102da610529366004613bfc565b611a6f565b61047a61053c366004614023565b611b6d565b6102da61054f36600461409a565b611d93565b600154610317906001600160a01b031681565b610317611e86565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b61059c611eb4565b60405161032491906140ba565b6102da6105b7366004613bfc565b611efa565b61059c6105ca366004613bfc565b6120a2565b6105e26105dd366004613bfc565b6120fb565b6040516103249291906140db565b6103176105fe366004613bfc565b5f908152601060205260409020546001600160a01b031690565b61047a610626366004614023565b612122565b610317610639366004613bfc565b5f908152600a60205260409020546001600160a01b031690565b6102da610661366004613f87565b6123ba565b6102da6106743660046140f1565b612451565b6102da610687366004613be1565b61253c565b6102da61069a36600461409a565b6125e3565b61047a6106ad366004613be1565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fb8565b6126c6565b6102da6106eb366004613bfc565b612779565b6107126106fe366004613bfc565b5f908152600d602052604090205460ff1690565b6040516103249190614129565b61043e61072d366004613f38565b6127b6565b6102da610740366004613be1565b6127c0565b6102da610753366004614137565b61285a565b600254610317906001600160a01b031681565b6102da610779366004613be1565b61296d565b6103c561078c366004613bfc565b6129a7565b6102da61079f366004613be1565b612b41565b6103176107b2366004613bfc565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be1565b612bd9565b5f6107e8612c68565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c92565b61089188612779565b61089a8c612b41565b6108a38b6127c0565b6108ac8a610945565b6108b589610a2d565b6108be87612ca3565b6108c7866123ba565b6108cf611e86565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d61296d565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612dd7565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612dd7565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c20565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c20565b60405180910390a150565b610ada612dd7565b610ae381612ca3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b319061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d9061416e565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610be99061416e565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c739061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f9061416e565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d18613826565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c89565b6003811115610d6657610d66613c89565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd89061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e049061416e565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e689061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e949061416e565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f309061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c9061416e565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612dd7565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612dd7565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c20565b5f611138613826565b5f60128161114960208701876141a0565b600381111561115a5761115a613c89565b600381111561116b5761116b613c89565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e96141b9565b602002015163ffffffff1611845f01602081019061120791906141a0565b906112265760405163286c068d60e11b815260040161099f91906141cd565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f91906112964260408901356141ef565b6112a09190614202565b6112aa9190614202565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be1565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be1565b906113325760405163295a6a6f60e11b815260040161099f9190613c20565b505f61133d866127b6565b60068054965090915085905f61135283614215565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f19190890135614202565b5f878152600e6020908152604090912060010191909155818652611417908801886141a0565b8560200190600381111561142d5761142d613c89565b9081600381111561144057611440613c89565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be1565b6001600160a01b031660a08601526114a3608088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb9088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261153890610100890190890161427c565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e09565b5f6115996080890160608a01613be1565b6001600160a01b031663fefd9a8b88846115b660808d018d61422d565b6115c360a08f018f61422d565b8f8060c001906115d3919061422d565b6040518963ffffffff1660e01b81526004016115f69897969594939291906142bf565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116369190614315565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c89565b0217905550604082015181600201556060820151816003019060026117309291906138a3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611775908261438b565b5060e0820151600882019061178a908261438b565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f2908261438b565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c90600401614440565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614485565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be1565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f6f565b60405180910390a2885f51602061491d5f395f51905f525f60016040516119279291906144a0565b60405180910390a250505050505050915091565b611943612dd7565b61194c5f612e76565b565b611956612dd7565b80515f5b818110156119aa57600b838281518110611976576119766141b9565b602002602001015160405161198b91906144bb565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da91906144d1565b60405180910390a15050565b6119ee612dd7565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f90614534565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c89565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614565565b5f828152600d60205260409020805460ff19166002179055601354611b079042614202565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061491d5f395f51905f5260016002604051611b619291906144a0565b60405180910390a25050565b5f5f611b7887610d10565b5f888152600d602052604090205490915060ff166004816006811115611ba057611ba0613c89565b1488600483909192611bc8576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611c2b576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f898152600860205260409020600d01611c48888a83614586565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611c8c92919061463a565b6040519081900381206001600160e01b031960e084901b168252611cb6918a908a90600401614649565b602060405180830381865afa158015611cd1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cf59190614485565b9350878785611d1957604051632f9f8ab960e01b815260040161099f92919061466b565b5050611d2489612ee6565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611d5692919061466b565b60405180910390a2885f51602061491d5f395f51905f5260046005604051611d7f9291906144a0565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611dbc5760405162461bcd60e51b815260040161099f90614534565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611dec57611dec613c89565b14611e1157836002826040516337e1404160e01b815260040161099f93929190614565565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061491d5f395f51905f5260026003604051611e789291906144a0565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611ed560405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f1f57611f1f613c89565b14611f5c5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611fae5760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611fc784613295565b5f858152601160205260409020546002549192506001600160a01b0390811691611ff49183911685613389565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061202a9088908790879087906004016146c1565b5f604051808303815f87803b158015612041575f5ffd5b505af1158015612053573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612093929190918252602082015260400190565b60405180910390a25050505050565b6120c360405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661211884826133b4565b9250925050915091565b5f5f61212d87610d10565b5f888152600d602052604090205490915060ff16600381600681111561215557612155613c89565b148860038390919261217d576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156121e1576040516308f3034360e31b81526004810192909252602482015260440161099f565b50506060830151602001518990428111156122185760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561224357604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161225592919061463a565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556015549091506122979042614202565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906122e4908d9085908c908c906004016146f8565b6020604051808303815f875af1158015612300573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123249190614485565b945088888661234857604051632f9f8ab960e01b815260040161099f92919061466b565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a60405161237c92919061466b565b60405180910390a2895f51602061491d5f395f51905f52600360046040516123a59291906144a0565b60405180910390a25050505095945050505050565b6123c2612dd7565b80515f5b81811015612421576001600b8483815181106123e4576123e46141b9565b60200260200101516040516123f991906144bb565b908152604051908190036020019020805491151560ff199092169190911790556001016123c6565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da91906144d1565b5f546001600160a01b031633148061247357506003546001600160a01b031633145b6124bf5760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124d55750600d60ff821611155b61251a5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b612538828260ff16600d81111561253357612533613c89565b61353c565b5050565b612544612dd7565b6001600160a01b03811661259a5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146126345760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561267e575f5ffd5b505af1158015612690573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126ce612dd7565b6001600160a01b038116158015906126ff57505f828152600960205260409020546001600160a01b03828116911614155b8290612721576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612781612dd7565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127c8612dd7565b6001600160a01b038116158015906127ee57506001546001600160a01b03828116911614155b819061280e576040516320252f0b60e01b815260040161099f9190613c20565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c20565b612862612dd7565b61286f602082018261472a565b63ffffffff16612885604083016020840161472a565b63ffffffff16101580156128aa57505f6128a2602083018361472a565b63ffffffff16115b6128ea5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290057612900613c89565b600381111561291157612911613c89565b815260208101919091526040015f2061292b9160026138e1565b5081600381111561293e5761293e613c89565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614743565b612975612dd7565b6001600160a01b03811661299e575f604051631e4fbdf760e01b815260040161099f9190613c20565b610ae381612e76565b5f818152600d602052604081205460ff16818160068111156129cb576129cb613c89565b036129f057826001826040516337e1404160e01b815260040161099f93929190614565565b6005816006811115612a0457612a04613c89565b03612a255760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3957612a39613c89565b03612a5a57604051633de16e3560e11b81526004810184905260240161099f565b5f612a6584836133b4565b9350905080612a8a57604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad357612ad3613c89565b0217905550835f51602061491d5f395f51905f52836006604051612af89291906144a0565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b32929190614781565b60405180910390a25050919050565b612b49612dd7565b6001600160a01b03811615801590612b6e57505f546001600160a01b03828116911614155b8190612b8e576040516375ac4eb760e11b815260040161099f9190613c20565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c20565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c155760405163b29d459560e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c20565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612c9a6136a4565b610ae3816136c9565b8035612ce65760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d325760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d815760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de0611e86565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c20565b6040516001600160a01b038481166024830152838116604483015260648201839052612e709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015612f2b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612f52919081019061479c565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003612ff0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590612fbc9088908890869060040161482b565b5f604051808303815f87803b158015612fd3575f5ffd5b505af1158015612fe5573d5f5f3e3d5ffd5b505050505050505050565b825f03613091575f858152601060205260409020546001600160a01b03168015613028576130286001600160a01b0383168285613389565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061305c9089908990879060040161482b565b5f604051808303815f87803b158015613073575f5ffd5b505af1158015613085573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156130aa576130aa6139d3565b6040519080825280602002602001820160405280156130d3578160200160208202803683370190505b5090505f6130e1858561485b565b90505f805b868110156131205782848281518110613101576131016141b9565b60209081029190910101526131168383614202565b91506001016130e6565b505f61312c82876141ef565b9050801561316957808461314160018a6141ef565b81518110613151576131516141b9565b602002602001018181516131659190614202565b9052505b600154613183906001600160a01b03878116911688613734565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906131b79088908c9089906004016148aa565b5f604051808303815f87803b1580156131ce575f5ffd5b505af11580156131e0573d5f5f3e3d5ffd5b50506001546131fe92506001600160a01b038881169250165f613734565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516132309291906148df565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326c908c908c908a9060040161482b565b5f604051808303815f87803b158015613283575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f818152600f602052604090205460609060ff16600181600d8111156132bd576132bd613c89565b14806132da5750600281600d8111156132d8576132d8613c89565b145b15613312575f5b60405190808252806020026020018201604052801561330a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa92505050801561337857506040513d5f823e601f3d908101601f19168201604052613375919081019061479c565b60015b613382575f6132e1565b9392505050565b6133af83846001600160a01b031663a9059cbb8585604051602401612e3e929190614903565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa15801561342e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134529190614315565b9050600185600681111561346857613468613c89565b14801561347457508042115b1561348757600180935093505050613535565b600285600681111561349b5761349b613c89565b1480156134a85750815142115b156134bc5760016003935093505050613535565b60038560068111156134d0576134d0613c89565b1480156134e05750816020015142115b156134f45760016006935093505050613535565b600485600681111561350857613508613c89565b1480156135185750816040015142115b1561352c576001600a935093505050613535565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561356057613560613c89565b0361358557826001826040516337e1404160e01b815260040161099f93929190614565565b600581600681111561359957613599613c89565b036135ba5760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135ce576135ce613c89565b036135ef57604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363857613638613c89565b0217905550825f51602061491d5f395f51905f5282600660405161365d9291906144a0565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051613697929190614781565b60405180910390a2505050565b6136ac6137c4565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b6129756136a4565b5f5f60205f8451602086015f885af1806136f0576040513d5f823e3d81fd5b50505f513d91508115613707578060011415613714565b6001600160a01b0384163b155b15612e705783604051635274afe760e01b815260040161099f9190613c20565b5f836001600160a01b031663095ea7b38484604051602401613757929190614903565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379084826137dd565b612e70576137ba84856001600160a01b031663095ea7b3865f604051602401612e3e929190614903565b612e7084826136d1565b5f6137cd612c68565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561381c5750811561380e578060011461381c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161384e61397d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d1579160200282015b828111156138d15782518255916020019190600101906138b6565b506138dd92915061399b565b5090565b6001830191839082156138d1579160200282015f5b8382111561394057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138f6565b80156139705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613940565b50506138dd92915061399b565b60405180604001604052806002906020820280368337509192915050565b5b808211156138dd575f815560010161399c565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a0f57613a0f6139d3565b604052919050565b5f6001600160401b03821115613a2f57613a2f6139d3565b5060051b60200190565b5f82601f830112613a48575f5ffd5b81356001600160401b03811115613a6157613a616139d3565b613a74601f8201601f19166020016139e7565b818152846020838601011115613a88575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab3575f5ffd5b8135613ac6613ac182613a17565b6139e7565b8082825260208201915060208360051b860101925085831115613ae7575f5ffd5b602085015b83811015613b275780356001600160401b03811115613b09575f5ffd5b613b18886020838a0101613a39565b84525060209283019201613aec565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b49575f5ffd5b8835613b54816139af565b97506020890135613b64816139af565b96506040890135613b74816139af565b95506060890135613b84816139af565b94506080890135613b94816139af565b935060a08901359250613baa8a60c08b016139c3565b91506101208901356001600160401b03811115613bc5575f5ffd5b613bd18b828c01613aa4565b9150509295985092959890939650565b5f60208284031215613bf1575f5ffd5b8135613382816139af565b5f60208284031215613c0c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c42575f5ffd5b919050565b5f5f60408385031215613c58575f5ffd5b613c6183613c34565b946020939093013593505050565b5f60608284031215613c7f575f5ffd5b61338283836139c3565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cad57613cad613c89565b9052565b60208101612c8c8284613c9d565b60048110613cad57613cad613c89565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d0d602082018f613cbf565b8c60408201528b6060820152613d26608082018c613c13565b6101c060a08201525f613d3d6101c083018c613ccf565b82810360c0840152613d4f818c613ccf565b9050613d5e60e084018b613c13565b613d6c61010084018a613c13565b8761012084015286610140840152828103610160840152613d8d8187613ccf565b915050613d9e610180830185613c13565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e70578151845260209384019390910190600101613dbd565b805182525f6020820151613df36020850182613cbf565b50604082015160408401526060820151613e106060850182613dba565b50608082015160a084015260a0820151613e2d60c0850182613c13565b5060c082015161020060e0850152613e49610200850182613ccf565b905060e0830151848203610100860152613e638282613ccf565b915050610100830151613e7a610120860182613c13565b50610120830151613e8f610140860182613c13565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec18282613ccf565b9150506101a0830151613ed86101c0860182613c13565b506101c08301518015156101e086015261330a565b602081525f6133826020830184613ddc565b5f60208284031215613f0f575f5ffd5b81356001600160401b03811115613f24575f5ffd5b613f3084828501613a39565b949350505050565b5f60208284031215613f48575f5ffd5b81356001600160401b03811115613f5d575f5ffd5b82016101008185031215613382575f5ffd5b828152604060208201525f613f306040830184613ddc565b5f60208284031215613f97575f5ffd5b81356001600160401b03811115613fac575f5ffd5b613f3084828501613aa4565b5f5f60408385031215613fc9575f5ffd5b823591506020830135613fdb816139af565b809150509250929050565b5f5f83601f840112613ff6575f5ffd5b5081356001600160401b0381111561400c575f5ffd5b602083019150836020828501011115613535575f5ffd5b5f5f5f5f5f60608688031215614037575f5ffd5b8535945060208601356001600160401b03811115614053575f5ffd5b61405f88828901613fe6565b90955093505060408601356001600160401b0381111561407d575f5ffd5b61408988828901613fe6565b969995985093965092949392505050565b5f5f604083850312156140ab575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c8c565b8215158152604081016133826020830184613c9d565b5f5f60408385031215614102575f5ffd5b82359150602083013560ff81168114613fdb575f5ffd5b60078110613cad57613cad613c89565b60208101612c8c8284614119565b5f5f60608385031215614148575f5ffd5b61415183613c34565b915083606084011115614162575f5ffd5b50926020919091019150565b600181811c9082168061418257607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f602082840312156141b0575f5ffd5b61338282613c34565b634e487b7160e01b5f52603260045260245ffd5b60208101612c8c8284613cbf565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c8c57612c8c6141db565b80820180821115612c8c57612c8c6141db565b5f60018201614226576142266141db565b5060010190565b5f5f8335601e19843603018112614242575f5ffd5b8301803591506001600160401b0382111561425b575f5ffd5b602001915036819003821315613535575f5ffd5b8015158114610ae3575f5ffd5b5f6020828403121561428c575f5ffd5b81356133828161426f565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6142de60a08301888a614297565b82810360608401526142f1818789614297565b90508281036080840152614306818587614297565b9b9a5050505050505050505050565b5f60208284031215614325575f5ffd5b5051919050565b601f8211156133af57805f5260205f20601f840160051c810160208510156143515750805b601f840160051c820191505b81811015614370575f815560010161435d565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b038111156143a4576143a46139d3565b6143b8816143b2845461416e565b8461432c565b6020601f8211600181146143e5575f83156143d35750848201515b6143dd8482614377565b855550614370565b5f84815260208120601f198516915b8281101561441457878501518255602094850194600190920191016143f4565b508482101561443157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561447a57815163ffffffff16835260209283019290910190600101614455565b505050949350505050565b5f60208284031215614495575f5ffd5b81516133828161426f565b604081016144ae8285614119565b6133826020830184614119565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561452857603f19878603018452614513858351613ccf565b945060209384019391909101906001016144f7565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016145796020830185614119565b613f306040830184614119565b6001600160401b0383111561459d5761459d6139d3565b6145b1836145ab835461416e565b8361432c565b5f601f8411600181146145dd575f85156145cb5750838201355b6145d58682614377565b845550614370565b5f83815260208120601f198716915b8281101561460c57868501358255602094850194600190920191016145ec565b5086821015614628575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f614662604083018486614297565b95945050505050565b602081525f613f30602083018486614297565b5f8151808452602084019350602083015f5b828110156146b75781516001600160a01b0316865260209586019590910190600101614690565b5093949350505050565b848152836020820152608060408201525f6146df608083018561467e565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f61381c606083018486614297565b803563ffffffff81168114613c42575f5ffd5b5f6020828403121561473a575f5ffd5b61338282614717565b6040810181835f5b60028110156147785763ffffffff61476283614717565b168352602092830192919091019060010161474b565b50505092915050565b6040810161478f8285614119565b6133826020830184613c9d565b5f602082840312156147ac575f5ffd5b81516001600160401b038111156147c1575f5ffd5b8201601f810184136147d1575f5ffd5b80516147df613ac182613a17565b8082825260208201915060208360051b850101925086831115614800575f5ffd5b6020840193505b8284101561381c57835161481a816139af565b825260209384019390910190614807565b838152606060208201525f614843606083018561467e565b905060018060a01b0383166040830152949350505050565b5f8261487557634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b828110156146b757815186526020958601959091019060010161488c565b6001600160a01b03841681526060602082018190525f906148cd9083018561467e565b828103604084015261381c818561487a565b604081525f6148f1604083018561467e565b8281036020840152614662818561487a565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c80638e5ce3ad11610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b80639c8570c8116101315780639c8570c814610618578063ac3d2f421461062b578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b80638e5ce3ad1461058157806390173a41146105945780639117173c146105a957806392312386146105bc578063929a8faf146105cf57806399c6679d146105f0575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b5780637edcd7ab1461052e57806381476ec21461054157806385814243146105545780638da5cb5b146105675780638dcdd86b1461056f575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b31565b6107df565b005b6102da6102ea366004613be1565b610945565b6103176102fd366004613bfc565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c20565b60405180910390f35b61031761033b366004613bfc565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c47565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be1565b610a2d565b6102da61039e366004613c6f565b610ad2565b6103c56103b1366004613bfc565b5f908152600f602052604090205460ff1690565b6040516103249190613cb1565b6103e56103e0366004613bfc565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613cfd565b61041261040d366004613bfc565b610d10565b6040516103249190613eed565b61043e61042d366004613bfc565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613eff565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613bfc565b61100d565b6102da6104ab366004613be1565b61109c565b6104c36104be366004613f38565b61112f565b604051610324929190613f6f565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f87565b61194e565b6102da610516366004613fb8565b6119e6565b6102da610529366004613bfc565b611a6f565b61047a61053c366004614023565b611b6d565b6102da61054f36600461409a565b611d93565b600154610317906001600160a01b031681565b610317611e86565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b61059c611eb4565b60405161032491906140ba565b6102da6105b7366004613bfc565b611efa565b61059c6105ca366004613bfc565b6120a2565b6105e26105dd366004613bfc565b6120fb565b6040516103249291906140db565b6103176105fe366004613bfc565b5f908152601060205260409020546001600160a01b031690565b61047a610626366004614023565b612122565b610317610639366004613bfc565b5f908152600a60205260409020546001600160a01b031690565b6102da610661366004613f87565b6123ba565b6102da6106743660046140f1565b612451565b6102da610687366004613be1565b61253c565b6102da61069a36600461409a565b6125e3565b61047a6106ad366004613be1565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fb8565b6126c6565b6102da6106eb366004613bfc565b612779565b6107126106fe366004613bfc565b5f908152600d602052604090205460ff1690565b6040516103249190614129565b61043e61072d366004613f38565b6127b6565b6102da610740366004613be1565b6127c0565b6102da610753366004614137565b61285a565b600254610317906001600160a01b031681565b6102da610779366004613be1565b61296d565b6103c561078c366004613bfc565b6129a7565b6102da61079f366004613be1565b612b41565b6103176107b2366004613bfc565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be1565b612bd9565b5f6107e8612c68565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c92565b61089188612779565b61089a8c612b41565b6108a38b6127c0565b6108ac8a610945565b6108b589610a2d565b6108be87612ca3565b6108c7866123ba565b6108cf611e86565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d61296d565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612dd7565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612dd7565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c20565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c20565b60405180910390a150565b610ada612dd7565b610ae381612ca3565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b319061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d9061416e565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610be99061416e565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c739061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f9061416e565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d18613826565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c89565b6003811115610d6657610d66613c89565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd89061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e049061416e565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e689061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e949061416e565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f309061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c9061416e565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612dd7565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612dd7565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c20565b5f611138613826565b5f60128161114960208701876141a0565b600381111561115a5761115a613c89565b600381111561116b5761116b613c89565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e96141b9565b602002015163ffffffff1611845f01602081019061120791906141a0565b906112265760405163286c068d60e11b815260040161099f91906141cd565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f91906112964260408901356141ef565b6112a09190614202565b6112aa9190614202565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be1565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be1565b906113325760405163295a6a6f60e11b815260040161099f9190613c20565b505f61133d866127b6565b60068054965090915085905f61135283614215565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f19190890135614202565b5f878152600e6020908152604090912060010191909155818652611417908801886141a0565b8560200190600381111561142d5761142d613c89565b9081600381111561144057611440613c89565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be1565b6001600160a01b031660a08601526114a3608088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb9088018861422d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261153890610100890190890161427c565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e09565b5f6115996080890160608a01613be1565b6001600160a01b031663fefd9a8b88846115b660808d018d61422d565b6115c360a08f018f61422d565b8f8060c001906115d3919061422d565b6040518963ffffffff1660e01b81526004016115f69897969594939291906142bf565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116369190614315565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c89565b0217905550604082015181600201556060820151816003019060026117309291906138a3565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c08201516007820190611775908261438b565b5060e0820151600882019061178a908261438b565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f2908261438b565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c90600401614440565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614485565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be1565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f6f565b60405180910390a2885f51602061491d5f395f51905f525f60016040516119279291906144a0565b60405180910390a250505050505050915091565b611943612dd7565b61194c5f612e76565b565b611956612dd7565b80515f5b818110156119aa57600b838281518110611976576119766141b9565b602002602001015160405161198b91906144bb565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da91906144d1565b60405180910390a15050565b6119ee612dd7565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f90614534565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c89565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614565565b5f828152600d60205260409020805460ff19166002179055601354611b079042614202565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f51602061491d5f395f51905f5260016002604051611b619291906144a0565b60405180910390a25050565b5f5f611b7887610d10565b5f888152600d602052604090205490915060ff166004816006811115611ba057611ba0613c89565b1488600483909192611bc8576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611c2b576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f898152600860205260409020600d01611c48888a83614586565b505f898152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b031663258ae5828989604051611c8c92919061463a565b6040519081900381206001600160e01b031960e084901b168252611cb6918a908a90600401614649565b602060405180830381865afa158015611cd1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cf59190614485565b9350878785611d1957604051632f9f8ab960e01b815260040161099f92919061466b565b5050611d2489612ee6565b887f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698989604051611d5692919061466b565b60405180910390a2885f51602061491d5f395f51905f5260046005604051611d7f9291906144a0565b60405180910390a250505095945050505050565b5f546001600160a01b03163314611dbc5760405162461bcd60e51b815260040161099f90614534565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611dec57611dec613c89565b14611e1157836002826040516337e1404160e01b815260040161099f93929190614565565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f51602061491d5f395f51905f5260026003604051611e789291906144a0565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611ed560405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611f1f57611f1f613c89565b14611f5c5760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611fae5760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611fc784613295565b5f858152601160205260409020546002549192506001600160a01b0390811691611ff49183911685613389565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b6979061202a9088908790879087906004016146c1565b5f604051808303815f87803b158015612041575f5ffd5b505af1158015612053573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051612093929190918252602082015260400190565b60405180910390a25050505050565b6120c360405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff1661211884826133b4565b9250925050915091565b5f5f61212d87610d10565b5f888152600d602052604090205490915060ff16600381600681111561215557612155613c89565b148860038390919261217d576040516337e1404160e01b815260040161099f93929190614565565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101839052600290910154928101929092528990428110156121e1576040516308f3034360e31b81526004810192909252602482015260440161099f565b50506060830151602001518990428111156122185760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561224357604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161225592919061463a565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff191660041790556015549091506122979042614202565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906122e4908d9085908c908c906004016146f8565b6020604051808303815f875af1158015612300573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123249190614485565b945088888661234857604051632f9f8ab960e01b815260040161099f92919061466b565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a60405161237c92919061466b565b60405180910390a2895f51602061491d5f395f51905f52600360046040516123a59291906144a0565b60405180910390a25050505095945050505050565b6123c2612dd7565b80515f5b81811015612421576001600b8483815181106123e4576123e46141b9565b60200260200101516040516123f991906144bb565b908152604051908190036020019020805491151560ff199092169190911790556001016123c6565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da91906144d1565b5f546001600160a01b031633148061247357506003546001600160a01b031633145b6124bf5760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124d55750600d60ff821611155b61251a5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b612538828260ff16600d81111561253357612533613c89565b61353c565b5050565b612544612dd7565b6001600160a01b03811661259a5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146126345760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b15801561267e575f5ffd5b505af1158015612690573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126ce612dd7565b6001600160a01b038116158015906126ff57505f828152600960205260409020546001600160a01b03828116911614155b8290612721576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612781612dd7565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127c8612dd7565b6001600160a01b038116158015906127ee57506001546001600160a01b03828116911614155b819061280e576040516320252f0b60e01b815260040161099f9190613c20565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c20565b612862612dd7565b61286f602082018261472a565b63ffffffff16612885604083016020840161472a565b63ffffffff16101580156128aa57505f6128a2602083018361472a565b63ffffffff16115b6128ea5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290057612900613c89565b600381111561291157612911613c89565b815260208101919091526040015f2061292b9160026138e1565b5081600381111561293e5761293e613c89565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614743565b612975612dd7565b6001600160a01b03811661299e575f604051631e4fbdf760e01b815260040161099f9190613c20565b610ae381612e76565b5f818152600d602052604081205460ff16818160068111156129cb576129cb613c89565b036129f057826001826040516337e1404160e01b815260040161099f93929190614565565b6005816006811115612a0457612a04613c89565b03612a255760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3957612a39613c89565b03612a5a57604051633de16e3560e11b81526004810184905260240161099f565b5f612a6584836133b4565b9350905080612a8a57604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad357612ad3613c89565b0217905550835f51602061491d5f395f51905f52836006604051612af89291906144a0565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b32929190614781565b60405180910390a25050919050565b612b49612dd7565b6001600160a01b03811615801590612b6e57505f546001600160a01b03828116911614155b8190612b8e576040516375ac4eb760e11b815260040161099f9190613c20565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c20565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c155760405163b29d459560e01b815260040161099f9190613c20565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c20565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612c9a6136a4565b610ae3816136c9565b8035612ce65760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d325760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d815760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de0611e86565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c20565b6040516001600160a01b038481166024830152838116604483015260648201839052612e709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d1565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015612f2b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612f52919081019061479c565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003612ff0576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590612fbc9088908890869060040161482b565b5f604051808303815f87803b158015612fd3575f5ffd5b505af1158015612fe5573d5f5f3e3d5ffd5b505050505050505050565b825f03613091575f858152601060205260409020546001600160a01b03168015613028576130286001600160a01b0383168285613389565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061305c9089908990879060040161482b565b5f604051808303815f87803b158015613073575f5ffd5b505af1158015613085573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b038111156130aa576130aa6139d3565b6040519080825280602002602001820160405280156130d3578160200160208202803683370190505b5090505f6130e1858561485b565b90505f805b868110156131205782848281518110613101576131016141b9565b60209081029190910101526131168383614202565b91506001016130e6565b505f61312c82876141ef565b9050801561316957808461314160018a6141ef565b81518110613151576131516141b9565b602002602001018181516131659190614202565b9052505b600154613183906001600160a01b03878116911688613734565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906131b79088908c9089906004016148aa565b5f604051808303815f87803b1580156131ce575f5ffd5b505af11580156131e0573d5f5f3e3d5ffd5b50506001546131fe92506001600160a01b038881169250165f613734565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516132309291906148df565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326c908c908c908a9060040161482b565b5f604051808303815f87803b158015613283575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f818152600f602052604090205460609060ff16600181600d8111156132bd576132bd613c89565b14806132da5750600281600d8111156132d8576132d8613c89565b145b15613312575f5b60405190808252806020026020018201604052801561330a578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa92505050801561337857506040513d5f823e601f3d908101601f19168201604052613375919081019061479c565b60015b613382575f6132e1565b9392505050565b6133af83846001600160a01b031663a9059cbb8585604051602401612e3e929190614903565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa15801561342e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134529190614315565b9050600185600681111561346857613468613c89565b14801561347457508042115b1561348757600180935093505050613535565b600285600681111561349b5761349b613c89565b1480156134a85750815142115b156134bc5760016003935093505050613535565b60038560068111156134d0576134d0613c89565b1480156134e05750816020015142115b156134f45760016006935093505050613535565b600485600681111561350857613508613c89565b1480156135185750816040015142115b1561352c576001600a935093505050613535565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561356057613560613c89565b0361358557826001826040516337e1404160e01b815260040161099f93929190614565565b600581600681111561359957613599613c89565b036135ba5760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135ce576135ce613c89565b036135ef57604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363857613638613c89565b0217905550825f51602061491d5f395f51905f5282600660405161365d9291906144a0565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051613697929190614781565b60405180910390a2505050565b6136ac6137c4565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b6129756136a4565b5f5f60205f8451602086015f885af1806136f0576040513d5f823e3d81fd5b50505f513d91508115613707578060011415613714565b6001600160a01b0384163b155b15612e705783604051635274afe760e01b815260040161099f9190613c20565b5f836001600160a01b031663095ea7b38484604051602401613757929190614903565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379084826137dd565b612e70576137ba84856001600160a01b031663095ea7b3865f604051602401612e3e929190614903565b612e7084826136d1565b5f6137cd612c68565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f51905082801561381c5750811561380e578060011461381c565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161384e61397d565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d1579160200282015b828111156138d15782518255916020019190600101906138b6565b506138dd92915061399b565b5090565b6001830191839082156138d1579160200282015f5b8382111561394057833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138f6565b80156139705782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613940565b50506138dd92915061399b565b60405180604001604052806002906020820280368337509192915050565b5b808211156138dd575f815560010161399c565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a0f57613a0f6139d3565b604052919050565b5f6001600160401b03821115613a2f57613a2f6139d3565b5060051b60200190565b5f82601f830112613a48575f5ffd5b81356001600160401b03811115613a6157613a616139d3565b613a74601f8201601f19166020016139e7565b818152846020838601011115613a88575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab3575f5ffd5b8135613ac6613ac182613a17565b6139e7565b8082825260208201915060208360051b860101925085831115613ae7575f5ffd5b602085015b83811015613b275780356001600160401b03811115613b09575f5ffd5b613b18886020838a0101613a39565b84525060209283019201613aec565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b49575f5ffd5b8835613b54816139af565b97506020890135613b64816139af565b96506040890135613b74816139af565b95506060890135613b84816139af565b94506080890135613b94816139af565b935060a08901359250613baa8a60c08b016139c3565b91506101208901356001600160401b03811115613bc5575f5ffd5b613bd18b828c01613aa4565b9150509295985092959890939650565b5f60208284031215613bf1575f5ffd5b8135613382816139af565b5f60208284031215613c0c575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c42575f5ffd5b919050565b5f5f60408385031215613c58575f5ffd5b613c6183613c34565b946020939093013593505050565b5f60608284031215613c7f575f5ffd5b61338283836139c3565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cad57613cad613c89565b9052565b60208101612c8c8284613c9d565b60048110613cad57613cad613c89565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d0d602082018f613cbf565b8c60408201528b6060820152613d26608082018c613c13565b6101c060a08201525f613d3d6101c083018c613ccf565b82810360c0840152613d4f818c613ccf565b9050613d5e60e084018b613c13565b613d6c61010084018a613c13565b8761012084015286610140840152828103610160840152613d8d8187613ccf565b915050613d9e610180830185613c13565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e70578151845260209384019390910190600101613dbd565b805182525f6020820151613df36020850182613cbf565b50604082015160408401526060820151613e106060850182613dba565b50608082015160a084015260a0820151613e2d60c0850182613c13565b5060c082015161020060e0850152613e49610200850182613ccf565b905060e0830151848203610100860152613e638282613ccf565b915050610100830151613e7a610120860182613c13565b50610120830151613e8f610140860182613c13565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec18282613ccf565b9150506101a0830151613ed86101c0860182613c13565b506101c08301518015156101e086015261330a565b602081525f6133826020830184613ddc565b5f60208284031215613f0f575f5ffd5b81356001600160401b03811115613f24575f5ffd5b613f3084828501613a39565b949350505050565b5f60208284031215613f48575f5ffd5b81356001600160401b03811115613f5d575f5ffd5b82016101008185031215613382575f5ffd5b828152604060208201525f613f306040830184613ddc565b5f60208284031215613f97575f5ffd5b81356001600160401b03811115613fac575f5ffd5b613f3084828501613aa4565b5f5f60408385031215613fc9575f5ffd5b823591506020830135613fdb816139af565b809150509250929050565b5f5f83601f840112613ff6575f5ffd5b5081356001600160401b0381111561400c575f5ffd5b602083019150836020828501011115613535575f5ffd5b5f5f5f5f5f60608688031215614037575f5ffd5b8535945060208601356001600160401b03811115614053575f5ffd5b61405f88828901613fe6565b90955093505060408601356001600160401b0381111561407d575f5ffd5b61408988828901613fe6565b969995985093965092949392505050565b5f5f604083850312156140ab575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c8c565b8215158152604081016133826020830184613c9d565b5f5f60408385031215614102575f5ffd5b82359150602083013560ff81168114613fdb575f5ffd5b60078110613cad57613cad613c89565b60208101612c8c8284614119565b5f5f60608385031215614148575f5ffd5b61415183613c34565b915083606084011115614162575f5ffd5b50926020919091019150565b600181811c9082168061418257607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f602082840312156141b0575f5ffd5b61338282613c34565b634e487b7160e01b5f52603260045260245ffd5b60208101612c8c8284613cbf565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c8c57612c8c6141db565b80820180821115612c8c57612c8c6141db565b5f60018201614226576142266141db565b5060010190565b5f5f8335601e19843603018112614242575f5ffd5b8301803591506001600160401b0382111561425b575f5ffd5b602001915036819003821315613535575f5ffd5b8015158114610ae3575f5ffd5b5f6020828403121561428c575f5ffd5b81356133828161426f565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f6142de60a08301888a614297565b82810360608401526142f1818789614297565b90508281036080840152614306818587614297565b9b9a5050505050505050505050565b5f60208284031215614325575f5ffd5b5051919050565b601f8211156133af57805f5260205f20601f840160051c810160208510156143515750805b601f840160051c820191505b81811015614370575f815560010161435d565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b038111156143a4576143a46139d3565b6143b8816143b2845461416e565b8461432c565b6020601f8211600181146143e5575f83156143d35750848201515b6143dd8482614377565b855550614370565b5f84815260208120601f198516915b8281101561441457878501518255602094850194600190920191016143f4565b508482101561443157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561447a57815163ffffffff16835260209283019290910190600101614455565b505050949350505050565b5f60208284031215614495575f5ffd5b81516133828161426f565b604081016144ae8285614119565b6133826020830184614119565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561452857603f19878603018452614513858351613ccf565b945060209384019391909101906001016144f7565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b838152606081016145796020830185614119565b613f306040830184614119565b6001600160401b0383111561459d5761459d6139d3565b6145b1836145ab835461416e565b8361432c565b5f601f8411600181146145dd575f85156145cb5750838201355b6145d58682614377565b845550614370565b5f83815260208120601f198716915b8281101561460c57868501358255602094850194600190920191016145ec565b5086821015614628575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b838152604060208201525f614662604083018486614297565b95945050505050565b602081525f613f30602083018486614297565b5f8151808452602084019350602083015f5b828110156146b75781516001600160a01b0316865260209586019590910190600101614690565b5093949350505050565b848152836020820152608060408201525f6146df608083018561467e565b905060018060a01b038316606083015295945050505050565b848152836020820152606060408201525f61381c606083018486614297565b803563ffffffff81168114613c42575f5ffd5b5f6020828403121561473a575f5ffd5b61338282614717565b6040810181835f5b60028110156147785763ffffffff61476283614717565b168352602092830192919091019060010161474b565b50505092915050565b6040810161478f8285614119565b6133826020830184613c9d565b5f602082840312156147ac575f5ffd5b81516001600160401b038111156147c1575f5ffd5b8201601f810184136147d1575f5ffd5b80516147df613ac182613a17565b8082825260208201915060208360051b850101925086831115614800575f5ffd5b6020840193505b8284101561381c57835161481a816139af565b825260209384019390910190614807565b838152606060208201525f614843606083018561467e565b905060018060a01b0383166040830152949350505050565b5f8261487557634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b828110156146b757815186526020958601959091019060010161488c565b6001600160a01b03841681526060602082018190525f906148cd9083018561467e565b828103604084015261381c818561487a565b604081525f6148f1604083018561467e565b8281036020840152614662818561487a565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b614a13806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c806390173a4111610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b8063ac3d2f4211610131578063ac3d2f4214610618578063b27392d514610640578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b806390173a41146105815780639117173c1461059657806392312386146105a9578063929a8faf146105bc57806399c6679d146105dd5780639c8570c814610605575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b57806381476ec21461052e57806385814243146105415780638da5cb5b146105545780638dcdd86b1461055c5780638e5ce3ad1461056e575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b37565b6107df565b005b6102da6102ea366004613be7565b610945565b6103176102fd366004613c02565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c26565b60405180910390f35b61031761033b366004613c02565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c4d565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be7565b610a2d565b6102da61039e366004613c75565b610ad2565b6103c56103b1366004613c02565b5f908152600f602052604090205460ff1690565b6040516103249190613cb7565b6103e56103e0366004613c02565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613d03565b61041261040d366004613c02565b610d10565b6040516103249190613ef3565b61043e61042d366004613c02565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613f05565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613c02565b61100d565b6102da6104ab366004613be7565b61109c565b6104c36104be366004613f3e565b61112f565b604051610324929190613f75565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f8d565b61194e565b6102da610516366004613fbe565b6119e6565b6102da610529366004613c02565b611a6f565b6102da61053c366004613fec565b611b6d565b600154610317906001600160a01b031681565b610317611c60565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b610589611c8e565b604051610324919061400c565b6102da6105a4366004613c02565b611cd4565b6105896105b7366004613c02565b611e7c565b6105cf6105ca366004613c02565b611ed5565b60405161032492919061402d565b6103176105eb366004613c02565b5f908152601060205260409020546001600160a01b031690565b61047a610613366004614080565b611efc565b610317610626366004613c02565b5f908152600a60205260409020546001600160a01b031690565b61047a61064e3660046140f7565b612194565b6102da610661366004613f8d565b6123c0565b6102da61067436600461419c565b612457565b6102da610687366004613be7565b612542565b6102da61069a366004613fec565b6125e9565b61047a6106ad366004613be7565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fbe565b6126cc565b6102da6106eb366004613c02565b61277f565b6107126106fe366004613c02565b5f908152600d602052604090205460ff1690565b60405161032491906141d4565b61043e61072d366004613f3e565b6127bc565b6102da610740366004613be7565b6127c6565b6102da6107533660046141e2565b612860565b600254610317906001600160a01b031681565b6102da610779366004613be7565b612973565b6103c561078c366004613c02565b6129ad565b6102da61079f366004613be7565b612b47565b6103176107b2366004613c02565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be7565b612bdf565b5f6107e8612c6e565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c98565b6108918861277f565b61089a8c612b47565b6108a38b6127c6565b6108ac8a610945565b6108b589610a2d565b6108be87612ca9565b6108c7866123c0565b6108cf611c60565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d612973565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612ddd565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612ddd565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c26565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c26565b60405180910390a150565b610ada612ddd565b610ae381612ca9565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b3190614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d90614219565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd90614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610be990614219565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c7390614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f90614219565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d1861382c565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c8f565b6003811115610d6657610d66613c8f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd890614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0490614219565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e6890614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9490614219565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f3090614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c90614219565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612ddd565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612ddd565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c26565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c26565b5f61113861382c565b5f601281611149602087018761424b565b600381111561115a5761115a613c8f565b600381111561116b5761116b613c8f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e9614264565b602002015163ffffffff1611845f016020810190611207919061424b565b906112265760405163286c068d60e11b815260040161099f9190614278565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f919061129642604089013561429a565b6112a091906142ad565b6112aa91906142ad565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be7565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be7565b906113325760405163295a6a6f60e11b815260040161099f9190613c26565b505f61133d866127bc565b60068054965090915085905f611352836142c0565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f191908901356142ad565b5f878152600e60209081526040909120600101919091558186526114179088018861424b565b8560200190600381111561142d5761142d613c8f565b9081600381111561144057611440613c8f565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be7565b6001600160a01b031660a08601526114a360808801886142d8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb908801886142d8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611538906101008901908901614327565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e0f565b5f6115996080890160608a01613be7565b6001600160a01b031663fefd9a8b88846115b660808d018d6142d8565b6115c360a08f018f6142d8565b8f8060c001906115d391906142d8565b6040518963ffffffff1660e01b81526004016115f698979695949392919061436a565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163691906143c0565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c8f565b0217905550604082015181600201556060820151816003019060026117309291906138a9565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c082015160078201906117759082614436565b5060e0820151600882019061178a9082614436565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f29082614436565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c906004016144eb565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614530565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be7565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f75565b60405180910390a2885f5160206149e75f395f51905f525f600160405161192792919061454b565b60405180910390a250505050505050915091565b611943612ddd565b61194c5f612e7c565b565b611956612ddd565b80515f5b818110156119aa57600b83828151811061197657611976614264565b602002602001015160405161198b9190614566565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da919061457c565b60405180910390a15050565b6119ee612ddd565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f906145df565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c8f565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614610565b5f828152600d60205260409020805460ff19166002179055601354611b0790426142ad565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206149e75f395f51905f5260016002604051611b6192919061454b565b60405180910390a25050565b5f546001600160a01b03163314611b965760405162461bcd60e51b815260040161099f906145df565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611bc657611bc6613c8f565b14611beb57836002826040516337e1404160e01b815260040161099f93929190614610565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206149e75f395f51905f5260026003604051611c5292919061454b565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611caf60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611cf957611cf9613c8f565b14611d365760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611d885760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611da184612eec565b5f858152601160205260409020546002549192506001600160a01b0390811691611dce9183911685612fe0565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611e04908890879087908790600401614674565b5f604051808303815f87803b158015611e1b575f5ffd5b505af1158015611e2d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611e6d929190918252602082015260400190565b60405180910390a25050505050565b611e9d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611ef2848261300b565b9250925050915091565b5f5f611f0787610d10565b5f888152600d602052604090205490915060ff166003816006811115611f2f57611f2f613c8f565b1488600383909192611f57576040516337e1404160e01b815260040161099f93929190614610565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611fbb576040516308f3034360e31b81526004810192909252602482015260440161099f565b5050606083015160200151899042811115611ff25760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561201d57604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161202f9291906146ab565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061207190426142ad565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906120be908d9085908c908c906004016146ba565b6020604051808303815f875af11580156120da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fe9190614530565b945088888661212257604051632f9f8ab960e01b815260040161099f9291906146d9565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516121569291906146d9565b60405180910390a2895f5160206149e75f395f51905f526003600460405161217f92919061454b565b60405180910390a25050505095945050505050565b5f5f61219f89610d10565b5f8a8152600d602052604090205490915060ff1660048160068111156121c7576121c7613c8f565b148a6004839091926121ef576040516337e1404160e01b815260040161099f93929190614610565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b9042811015612252576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f8b8152600860205260409020600d0161226f8a8c836146ec565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b6040516122b39291906146ab565b6040519081900381206001600160e01b031960e084901b1682526122e1918c908c908c908c906004016147a0565b602060405180830381865afa1580156122fc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123209190614530565b935089898561234457604051632f9f8ab960e01b815260040161099f9291906146d9565b505061234f8b613193565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516123819291906146d9565b60405180910390a28a5f5160206149e75f395f51905f52600460056040516123aa92919061454b565b60405180910390a2505050979650505050505050565b6123c8612ddd565b80515f5b81811015612427576001600b8483815181106123ea576123ea614264565b60200260200101516040516123ff9190614566565b908152604051908190036020019020805491151560ff199092169190911790556001016123cc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da919061457c565b5f546001600160a01b031633148061247957506003546001600160a01b031633145b6124c55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124db5750600d60ff821611155b6125205760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b61253e828260ff16600d81111561253957612539613c8f565b613542565b5050565b61254a612ddd565b6001600160a01b0381166125a05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b0316331461263a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612684575f5ffd5b505af1158015612696573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126d4612ddd565b6001600160a01b0381161580159061270557505f828152600960205260409020546001600160a01b03828116911614155b8290612727576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612787612ddd565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127ce612ddd565b6001600160a01b038116158015906127f457506001546001600160a01b03828116911614155b8190612814576040516320252f0b60e01b815260040161099f9190613c26565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c26565b612868612ddd565b61287560208201826147eb565b63ffffffff1661288b60408301602084016147eb565b63ffffffff16101580156128b057505f6128a860208301836147eb565b63ffffffff16115b6128f05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290657612906613c8f565b600381111561291757612917613c8f565b815260208101919091526040015f206129319160026138e7565b5081600381111561294457612944613c8f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614804565b61297b612ddd565b6001600160a01b0381166129a4575f604051631e4fbdf760e01b815260040161099f9190613c26565b610ae381612e7c565b5f818152600d602052604081205460ff16818160068111156129d1576129d1613c8f565b036129f657826001826040516337e1404160e01b815260040161099f93929190614610565b6005816006811115612a0a57612a0a613c8f565b03612a2b5760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3f57612a3f613c8f565b03612a6057604051633de16e3560e11b81526004810184905260240161099f565b5f612a6b848361300b565b9350905080612a9057604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad957612ad9613c8f565b0217905550835f5160206149e75f395f51905f52836006604051612afe92919061454b565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b38929190614842565b60405180910390a25050919050565b612b4f612ddd565b6001600160a01b03811615801590612b7457505f546001600160a01b03828116911614155b8190612b94576040516375ac4eb760e11b815260040161099f9190613c26565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c26565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c1b5760405163b29d459560e01b815260040161099f9190613c26565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c26565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612ca06136aa565b610ae3816136cf565b8035612cec5760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d385760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d875760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de6611c60565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c26565b6040516001600160a01b038481166024830152838116604483015260648201839052612e769186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d7565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115612f1457612f14613c8f565b1480612f315750600281600d811115612f2f57612f2f613c8f565b145b15612f69575f5b604051908082528060200260200182016040528015612f61578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015612fcf57506040513d5f823e601f3d908101601f19168201604052612fcc919081019061485d565b60015b612fd9575f612f38565b9392505050565b61300683846001600160a01b031663a9059cbb8585604051602401612e449291906148ec565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613085573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a991906143c0565b905060018560068111156130bf576130bf613c8f565b1480156130cb57508042115b156130de5760018093509350505061318c565b60028560068111156130f2576130f2613c8f565b1480156130ff5750815142115b15613113576001600393509350505061318c565b600385600681111561312757613127613c8f565b1480156131375750816020015142115b1561314b576001600693509350505061318c565b600485600681111561315f5761315f613c8f565b14801561316f5750816040015142115b15613183576001600a93509350505061318c565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa1580156131d8573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526131ff919081019061485d565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361329d576002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326990889088908690600401614905565b5f604051808303815f87803b158015613280575f5ffd5b505af1158015613292573d5f5f3e3d5ffd5b505050505050505050565b825f0361333e575f858152601060205260409020546001600160a01b031680156132d5576132d56001600160a01b0383168285612fe0565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061330990899089908790600401614905565b5f604051808303815f87803b158015613320575f5ffd5b505af1158015613332573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b03811115613357576133576139d9565b604051908082528060200260200182016040528015613380578160200160208202803683370190505b5090505f61338e8585614935565b90505f805b868110156133cd57828482815181106133ae576133ae614264565b60209081029190910101526133c383836142ad565b9150600101613393565b505f6133d9828761429a565b905080156134165780846133ee60018a61429a565b815181106133fe576133fe614264565b6020026020010181815161341291906142ad565b9052505b600154613430906001600160a01b0387811691168861373a565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906134649088908c908990600401614984565b5f604051808303815f87803b15801561347b575f5ffd5b505af115801561348d573d5f5f3e3d5ffd5b50506001546134ab92506001600160a01b038881169250165f61373a565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516134dd9291906149b9565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613519908c908c908a90600401614905565b5f604051808303815f87803b158015613530575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f828152600d602052604081205460ff169081600681111561356657613566613c8f565b0361358b57826001826040516337e1404160e01b815260040161099f93929190614610565b600581600681111561359f5761359f613c8f565b036135c05760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135d4576135d4613c8f565b036135f557604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363e5761363e613c8f565b0217905550825f5160206149e75f395f51905f5282600660405161366392919061454b565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161369d929190614842565b60405180910390a2505050565b6136b26137ca565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b61297b6136aa565b5f5f60205f8451602086015f885af1806136f6576040513d5f823e3d81fd5b50505f513d9150811561370d57806001141561371a565b6001600160a01b0384163b155b15612e765783604051635274afe760e01b815260040161099f9190613c26565b5f836001600160a01b031663095ea7b3848460405160240161375d9291906148ec565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379684826137e3565b612e76576137c084856001600160a01b031663095ea7b3865f604051602401612e449291906148ec565b612e7684826136d7565b5f6137d3612c6e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015613822575081156138145780600114613822565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001613854613983565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d7579160200282015b828111156138d75782518255916020019190600101906138bc565b506138e39291506139a1565b5090565b6001830191839082156138d7579160200282015f5b8382111561394657833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138fc565b80156139765782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613946565b50506138e39291506139a1565b60405180604001604052806002906020820280368337509192915050565b5b808211156138e3575f81556001016139a2565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a1557613a156139d9565b604052919050565b5f6001600160401b03821115613a3557613a356139d9565b5060051b60200190565b5f82601f830112613a4e575f5ffd5b81356001600160401b03811115613a6757613a676139d9565b613a7a601f8201601f19166020016139ed565b818152846020838601011115613a8e575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab9575f5ffd5b8135613acc613ac782613a1d565b6139ed565b8082825260208201915060208360051b860101925085831115613aed575f5ffd5b602085015b83811015613b2d5780356001600160401b03811115613b0f575f5ffd5b613b1e886020838a0101613a3f565b84525060209283019201613af2565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b4f575f5ffd5b8835613b5a816139b5565b97506020890135613b6a816139b5565b96506040890135613b7a816139b5565b95506060890135613b8a816139b5565b94506080890135613b9a816139b5565b935060a08901359250613bb08a60c08b016139c9565b91506101208901356001600160401b03811115613bcb575f5ffd5b613bd78b828c01613aaa565b9150509295985092959890939650565b5f60208284031215613bf7575f5ffd5b8135612fd9816139b5565b5f60208284031215613c12575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c48575f5ffd5b919050565b5f5f60408385031215613c5e575f5ffd5b613c6783613c3a565b946020939093013593505050565b5f60608284031215613c85575f5ffd5b612fd983836139c9565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cb357613cb3613c8f565b9052565b60208101612c928284613ca3565b60048110613cb357613cb3613c8f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d13602082018f613cc5565b8c60408201528b6060820152613d2c608082018c613c19565b6101c060a08201525f613d436101c083018c613cd5565b82810360c0840152613d55818c613cd5565b9050613d6460e084018b613c19565b613d7261010084018a613c19565b8761012084015286610140840152828103610160840152613d938187613cd5565b915050613da4610180830185613c19565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e76578151845260209384019390910190600101613dc3565b805182525f6020820151613df96020850182613cc5565b50604082015160408401526060820151613e166060850182613dc0565b50608082015160a084015260a0820151613e3360c0850182613c19565b5060c082015161020060e0850152613e4f610200850182613cd5565b905060e0830151848203610100860152613e698282613cd5565b915050610100830151613e80610120860182613c19565b50610120830151613e95610140860182613c19565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec78282613cd5565b9150506101a0830151613ede6101c0860182613c19565b506101c08301518015156101e0860152612f61565b602081525f612fd96020830184613de2565b5f60208284031215613f15575f5ffd5b81356001600160401b03811115613f2a575f5ffd5b613f3684828501613a3f565b949350505050565b5f60208284031215613f4e575f5ffd5b81356001600160401b03811115613f63575f5ffd5b82016101008185031215612fd9575f5ffd5b828152604060208201525f613f366040830184613de2565b5f60208284031215613f9d575f5ffd5b81356001600160401b03811115613fb2575f5ffd5b613f3684828501613aaa565b5f5f60408385031215613fcf575f5ffd5b823591506020830135613fe1816139b5565b809150509250929050565b5f5f60408385031215613ffd575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c92565b821515815260408101612fd96020830184613ca3565b5f5f83601f840112614053575f5ffd5b5081356001600160401b03811115614069575f5ffd5b60208301915083602082850101111561318c575f5ffd5b5f5f5f5f5f60608688031215614094575f5ffd5b8535945060208601356001600160401b038111156140b0575f5ffd5b6140bc88828901614043565b90955093505060408601356001600160401b038111156140da575f5ffd5b6140e688828901614043565b969995985093965092949392505050565b5f5f5f5f5f5f5f6080888a03121561410d575f5ffd5b8735965060208801356001600160401b03811115614129575f5ffd5b6141358a828b01614043565b90975095505060408801356001600160401b03811115614153575f5ffd5b61415f8a828b01614043565b90955093505060608801356001600160401b0381111561417d575f5ffd5b6141898a828b01614043565b989b979a50959850939692959293505050565b5f5f604083850312156141ad575f5ffd5b82359150602083013560ff81168114613fe1575f5ffd5b60078110613cb357613cb3613c8f565b60208101612c9282846141c4565b5f5f606083850312156141f3575f5ffd5b6141fc83613c3a565b91508360608401111561420d575f5ffd5b50926020919091019150565b600181811c9082168061422d57607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f6020828403121561425b575f5ffd5b612fd982613c3a565b634e487b7160e01b5f52603260045260245ffd5b60208101612c928284613cc5565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c9257612c92614286565b80820180821115612c9257612c92614286565b5f600182016142d1576142d1614286565b5060010190565b5f5f8335601e198436030181126142ed575f5ffd5b8301803591506001600160401b03821115614306575f5ffd5b60200191503681900382131561318c575f5ffd5b8015158114610ae3575f5ffd5b5f60208284031215614337575f5ffd5b8135612fd98161431a565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f61438960a08301888a614342565b828103606084015261439c818789614342565b905082810360808401526143b1818587614342565b9b9a5050505050505050505050565b5f602082840312156143d0575f5ffd5b5051919050565b601f82111561300657805f5260205f20601f840160051c810160208510156143fc5750805b601f840160051c820191505b8181101561441b575f8155600101614408565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b0381111561444f5761444f6139d9565b6144638161445d8454614219565b846143d7565b6020601f821160018114614490575f831561447e5750848201515b6144888482614422565b85555061441b565b5f84815260208120601f198516915b828110156144bf578785015182556020948501946001909201910161449f565b50848210156144dc57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561452557815163ffffffff16835260209283019290910190600101614500565b505050949350505050565b5f60208284031215614540575f5ffd5b8151612fd98161431a565b6040810161455982856141c4565b612fd960208301846141c4565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156145d357603f198786030184526145be858351613cd5565b945060209384019391909101906001016145a2565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161462460208301856141c4565b613f3660408301846141c4565b5f8151808452602084019350602083015f5b8281101561466a5781516001600160a01b0316865260209586019590910190600101614643565b5093949350505050565b848152836020820152608060408201525f6146926080830185614631565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f613822606083018486614342565b602081525f613f36602083018486614342565b6001600160401b03831115614703576147036139d9565b614717836147118354614219565b836143d7565b5f601f841160018114614743575f85156147315750838201355b61473b8682614422565b84555061441b565b5f83815260208120601f198716915b828110156147725786850135825560209485019460019092019101614752565b508682101561478e575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6147b9606083018688614342565b82810360408401526147cc818587614342565b98975050505050505050565b803563ffffffff81168114613c48575f5ffd5b5f602082840312156147fb575f5ffd5b612fd9826147d8565b6040810181835f5b60028110156148395763ffffffff614823836147d8565b168352602092830192919091019060010161480c565b50505092915050565b6040810161485082856141c4565b612fd96020830184613ca3565b5f6020828403121561486d575f5ffd5b81516001600160401b03811115614882575f5ffd5b8201601f81018413614892575f5ffd5b80516148a0613ac782613a1d565b8082825260208201915060208360051b8501019250868311156148c1575f5ffd5b6020840193505b828410156138225783516148db816139b5565b8252602093840193909101906148c8565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f61491d6060830185614631565b905060018060a01b0383166040830152949350505050565b5f8261494f57634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b8281101561466a578151865260209586019590910190600101614966565b6001600160a01b03841681526060602082018190525f906149a790830185614631565b82810360408401526138228185614954565b604081525f6149cb6040830185614631565b82810360208401526149dd8185614954565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102c3575f3560e01c806390173a4111610177578063cb649617116100d5578063ea71aa571161008f578063ea71aa5714610745578063f0691cba14610758578063f2fde38b1461076b578063f81b8ef61461077e578063fad8e11114610791578063fbdb3237146107a4578063fd2f3d01146107cc575f5ffd5b8063cb649617146106c1578063cbd16872146106ca578063cf0f34c4146106dd578063cfbdc98d146106f0578063da16fb2f1461071f578063e59e469514610732575f5ffd5b8063ac3d2f4211610131578063ac3d2f4214610618578063b27392d514610640578063b68fd1be14610653578063bb2d1b8214610666578063bff232c114610679578063c1ab0f1f1461068c578063c4ccafa21461069f575f5ffd5b806390173a41146105815780639117173c1461059657806392312386146105a9578063929a8faf146105bc57806399c6679d146105dd5780639c8570c814610605575f5ffd5b80634fc77264116102245780637c8c3b4d116101de5780637c8c3b4d146105085780637cfa9d741461051b57806381476ec21461052e57806385814243146105415780638da5cb5b146105545780638dcdd86b1461055c5780638e5ce3ad1461056e575f5ffd5b80634fc772641461049d57806364226409146104b0578063647846a5146104d15780636db5c8fd146104e4578063715018a6146104ed57806377868ae4146104f5575f5ffd5b80631ba72945116102805780631ba729451461039057806336c5d38a146103a35780634017daf0146103d2578063406ed35c146103ff5780634147a3601461041f578063459d92941461044c5780634e92ec631461048a575f5ffd5b806301d12f1c146102c757806302a3a9c9146102dc5780630ef81b2f146102ef57806310bc62811461032d57806311bd61d91461035557806315cce2241461037d575b5f5ffd5b6102da6102d5366004613b37565b6107df565b005b6102da6102ea366004613be7565b610945565b6103176102fd366004613c02565b5f908152600960205260409020546001600160a01b031690565b6040516103249190613c26565b60405180910390f35b61031761033b366004613c02565b60096020525f90815260409020546001600160a01b031681565b610368610363366004613c4d565b6109f1565b60405163ffffffff9091168152602001610324565b6102da61038b366004613be7565b610a2d565b6102da61039e366004613c75565b610ad2565b6103c56103b1366004613c02565b5f908152600f602052604090205460ff1690565b6040516103249190613cb7565b6103e56103e0366004613c02565b610ae6565b6040516103249e9d9c9b9a99989796959493929190613d03565b61041261040d366004613c02565b610d10565b6040516103249190613ef3565b61043e61042d366004613c02565b600c6020525f908152604090205481565b604051908152602001610324565b61047a61045a366004613f05565b8051602081830181018051600b8252928201919093012091525460ff1681565b6040519015158152602001610324565b6102da610498366004613c02565b61100d565b6102da6104ab366004613be7565b61109c565b6104c36104be366004613f3e565b61112f565b604051610324929190613f75565b600454610317906001600160a01b031681565b61043e60055481565b6102da61193b565b6102da610503366004613f8d565b61194e565b6102da610516366004613fbe565b6119e6565b6102da610529366004613c02565b611a6f565b6102da61053c366004613fec565b611b6d565b600154610317906001600160a01b031681565b610317611c60565b5f54610317906001600160a01b031681565b600354610317906001600160a01b031681565b610589611c8e565b604051610324919061400c565b6102da6105a4366004613c02565b611cd4565b6105896105b7366004613c02565b611e7c565b6105cf6105ca366004613c02565b611ed5565b60405161032492919061402d565b6103176105eb366004613c02565b5f908152601060205260409020546001600160a01b031690565b61047a610613366004614080565b611efc565b610317610626366004613c02565b5f908152600a60205260409020546001600160a01b031690565b61047a61064e3660046140f7565b612194565b6102da610661366004613f8d565b6123c0565b6102da61067436600461419c565b612457565b6102da610687366004613be7565b612542565b6102da61069a366004613fec565b6125e9565b61047a6106ad366004613be7565b60076020525f908152604090205460ff1681565b61043e60065481565b6102da6106d8366004613fbe565b6126cc565b6102da6106eb366004613c02565b61277f565b6107126106fe366004613c02565b5f908152600d602052604090205460ff1690565b60405161032491906141d4565b61043e61072d366004613f3e565b6127bc565b6102da610740366004613be7565b6127c6565b6102da6107533660046141e2565b612860565b600254610317906001600160a01b031681565b6102da610779366004613be7565b612973565b6103c561078c366004613c02565b6129ad565b6102da61079f366004613be7565b612b47565b6103176107b2366004613c02565b600a6020525f90815260409020546001600160a01b031681565b6102da6107da366004613be7565b612bdf565b5f6107e8612c6e565b805490915060ff600160401b82041615906001600160401b03165f8115801561080e5750825b90505f826001600160401b031660011480156108295750303b155b905081158015610837575080155b156108555760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561087f57845460ff60401b1916600160401b1785555b61088833612c98565b6108918861277f565b61089a8c612b47565b6108a38b6127c6565b6108ac8a610945565b6108b589610a2d565b6108be87612ca9565b6108c7866123c0565b6108cf611c60565b6001600160a01b03168d6001600160a01b0316146108f0576108f08d612973565b831561093657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050505050565b61094d612ddd565b6001600160a01b0381166109a85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f208160028110610a0a575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a35612ddd565b6001600160a01b03811615801590610a5b57506004546001600160a01b03828116911614155b8190610a7b5760405163eddf07f560e01b815260040161099f9190613c26565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ac7908390613c26565b60405180910390a150565b610ada612ddd565b610ae381612ca9565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff90951695939492936001600160a01b039092169291610b3190614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d90614219565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b505050505090806008018054610bbd90614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610be990614219565b8015610c345780601f10610c0b57610100808354040283529160200191610c34565b820191905f5260205f20905b815481529060010190602001808311610c1757829003601f168201915b5050506009840154600a850154600b860154600c870154600d8801805497986001600160a01b03958616989490951696509194509291610c7390614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9f90614219565b8015610cea5780601f10610cc157610100808354040283529160200191610cea565b820191905f5260205f20905b815481529060010190602001808311610ccd57829003601f168201915b505050600e90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610d1861382c565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610d5557610d55613c8f565b6003811115610d6657610d66613c8f565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610d8b5750505091835250506005820154602082015260068201546001600160a01b03166040820152600782018054606090920191610dd890614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0490614219565b8015610e4f5780601f10610e2657610100808354040283529160200191610e4f565b820191905f5260205f20905b815481529060010190602001808311610e3257829003601f168201915b50505050508152602001600882018054610e6890614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9490614219565b8015610edf5780601f10610eb657610100808354040283529160200191610edf565b820191905f5260205f20905b815481529060010190602001808311610ec257829003601f168201915b505050918352505060098201546001600160a01b039081166020830152600a830154166040820152600b8201546060820152600c8201546080820152600d8201805460a090920191610f3090614219565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5c90614219565b8015610fa75780601f10610f7e57610100808354040283529160200191610fa7565b820191905f5260205f20905b815481529060010190602001808311610f8a57829003601f168201915b5050509183525050600e91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a08201519192508391166110075760405163cd6f4a4f60e01b815260040161099f91815260200190565b50919050565b611015612ddd565b5f8181526009602052604090205481906001600160a01b031661104e576040516381c4951960e01b815260040161099f91815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ac79083815260200190565b6110a4612ddd565b6001600160a01b0381165f90815260076020526040902054819060ff166110df576040516321ac7c5f60e01b815260040161099f9190613c26565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ac7908390613c26565b5f61113861382c565b5f601281611149602087018761424b565b600381111561115a5761115a613c8f565b600381111561116b5761116b613c8f565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611192579050505050505090505f816001600281106111e9576111e9614264565b602002015163ffffffff1611845f016020810190611207919061424b565b906112265760405163286c068d60e11b815260040161099f9190614278565b5060208401354281101561125057604051630b99e87960e01b815260040161099f91815260200190565b506040840135602085013581101561127e5760405163174b5a0760e21b815260040161099f91815260200190565b506015546014545f919061129642604089013561429a565b6112a091906142ad565b6112aa91906142ad565b9050600554811081906112d3576040516313b783af60e21b815260040161099f91815260200190565b5060075f6112e76080880160608901613be7565b6001600160a01b0316815260208101919091526040015f205460ff166113136080870160608801613be7565b906113325760405163295a6a6f60e11b815260040161099f9190613c26565b505f61133d866127bc565b60068054965090915085905f611352836142c0565b9091555050604080514460208201529081018690525f9060600160408051808303601f1901815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b039092166001600160a01b0319928316179055600d8552838220805460ff1916600117905560109094528290208054339416939093179092556014549192506113f191908901356142ad565b5f878152600e60209081526040909120600101919091558186526114179088018861424b565b8560200190600381111561142d5761142d613c8f565b9081600381111561144057611440613c8f565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526114889060808901908901613be7565b6001600160a01b031660a08601526114a360808801886142d8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060c0808701919091526114eb908801886142d8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e080870191909152611538906101008901908901614327565b15156101c08601525f610140860181905261016086018190526040805160208101909152908152610180860152336101a08601819052600454611588916001600160a01b03909116903085612e0f565b5f6115996080890160608a01613be7565b6001600160a01b031663fefd9a8b88846115b660808d018d6142d8565b6115c360a08f018f6142d8565b8f8060c001906115d391906142d8565b6040518963ffffffff1660e01b81526004016115f698979695949392919061436a565b6020604051808303815f875af1158015611612573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163691906143c0565b5f818152600960205260409020549091506001600160a01b03168181611672576040516381c4951960e01b815260040161099f91815260200190565b505f828152600a60205260409020546001600160a01b031682816116ac576040516381c4951960e01b815260040161099f91815260200190565b50608088018390526001600160a01b038083166101008a015281166101208901525f8981526008602090815260409091208951815590890151600180830180548c94939260ff19919091169083600381111561170a5761170a613c8f565b0217905550604082015181600201556060820151816003019060026117309291906138a9565b506080820151600582015560a08201516006820180546001600160a01b0319166001600160a01b0390921691909117905560c082015160078201906117759082614436565b5060e0820151600882019061178a9082614436565b506101008201516009820180546001600160a01b039283166001600160a01b031991821617909155610120840151600a84018054919093169116179055610140820151600b820155610160820151600c820155610180820151600d8201906117f29082614436565b506101a0820151600e90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90611858908c9088908c906004016144eb565b6020604051808303815f875af1158015611874573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118989190614530565b6118b557604051630d8dbe2560e01b815260040160405180910390fd5b6118c560808b0160608c01613be7565b6001600160a01b03167f5904e83d57e704fba4d92c5617f6b50ae993cd42d78babfcb239d0a6775f30708a8a6040516118ff929190613f75565b60405180910390a2885f5160206149e75f395f51905f525f600160405161192792919061454b565b60405180910390a250505050505050915091565b611943612ddd565b61194c5f612e7c565b565b611956612ddd565b80515f5b818110156119aa57600b83828151811061197657611976614264565b602002602001015160405161198b9190614566565b908152604051908190036020019020805460ff1916905560010161195a565b507fd1b46e030b48add7bc03225cc5a6f403970976b36983f99ec31d535d627fc7db826040516119da919061457c565b60405180910390a15050565b6119ee612ddd565b6001600160a01b03811615801590611a1f57505f828152600a60205260409020546001600160a01b03828116911614155b8290611a41576040516381c4951960e01b815260040161099f91815260200190565b505f918252600a602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b5f546001600160a01b03163314611a985760405162461bcd60e51b815260040161099f906145df565b5f818152600d602052604090205460ff166001816006811115611abd57611abd613c8f565b14611ae257816001826040516337e1404160e01b815260040161099f93929190614610565b5f828152600d60205260409020805460ff19166002179055601354611b0790426142ad565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206149e75f395f51905f5260016002604051611b6192919061454b565b60405180910390a25050565b5f546001600160a01b03163314611b965760405162461bcd60e51b815260040161099f906145df565b5f828152600860209081526040808320600d9092529091205460ff166002816006811115611bc657611bc6613c8f565b14611beb57836002826040516337e1404160e01b815260040161099f93929190614610565b5f848152600d6020526040808220805460ff19166003179055600b84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206149e75f395f51905f5260026003604051611c5292919061454b565b60405180910390a250505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b611caf60405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601354815260145460208201526015549181019190915290565b5f818152600d602052604090205460ff166006816006811115611cf957611cf9613c8f565b14611d365760405162461bcd60e51b815260206004820152600d60248201526c114cc81b9bdd0819985a5b1959609a1b604482015260640161099f565b5f828152600c602052604090205480611d885760405162461bcd60e51b8152602060048201526014602482015273139bc81c185e5b595b9d081d1bc81c99599d5b9960621b604482015260640161099f565b5f838152600c60205260408120819055611da184612eec565b5f858152601160205260409020546002549192506001600160a01b0390811691611dce9183911685612fe0565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611e04908890879087908790600401614674565b5f604051808303815f87803b158015611e1b575f5ffd5b505af1158015611e2d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611e6d929190918252602082015260400190565b60405180910390a25050505050565b611e9d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611ef2848261300b565b9250925050915091565b5f5f611f0787610d10565b5f888152600d602052604090205490915060ff166003816006811115611f2f57611f2f613c8f565b1488600383909192611f57576040516337e1404160e01b815260040161099f93929190614610565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611fbb576040516308f3034360e31b81526004810192909252602482015260440161099f565b5050606083015160200151899042811115611ff25760405163017e35e560e71b81526004810192909252602482015260440161099f565b505061016083015189901561201d57604051637eb9cea960e11b815260040161099f91815260200190565b505f888860405161202f9291906146ab565b60408051918290039091205f8c815260086020908152838220600c01839055600d905291909120805460ff1916600417905560155490915061207190426142ad565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf906120be908d9085908c908c906004016146ba565b6020604051808303815f875af11580156120da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fe9190614530565b945088888661212257604051632f9f8ab960e01b815260040161099f9291906146d9565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a6040516121569291906146d9565b60405180910390a2895f5160206149e75f395f51905f526003600460405161217f92919061454b565b60405180910390a25050505095945050505050565b5f5f61219f89610d10565b5f8a8152600d602052604090205490915060ff1660048160068111156121c7576121c7613c8f565b148a6004839091926121ef576040516337e1404160e01b815260040161099f93929190614610565b5050505f8a8152600e602090815260409182902082516060810184528154815260018201549281019290925260020154918101829052908b9042811015612252576040516308f3034360e31b81526004810192909252602482015260440161099f565b50505f8b8152600860205260409020600d0161226f8a8c836146ec565b505f8b8152600d6020526040902080546005919060ff191660018302179055508261010001516001600160a01b0316635bf48e3a8b8b6040516122b39291906146ab565b6040519081900381206001600160e01b031960e084901b1682526122e1918c908c908c908c906004016147a0565b602060405180830381865afa1580156122fc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123209190614530565b935089898561234457604051632f9f8ab960e01b815260040161099f9291906146d9565b505061234f8b613193565b8a7f02a24c3402076671e129905ba4579d884b1f94ded1c07fc03d26d11b60bca1698b8b6040516123819291906146d9565b60405180910390a28a5f5160206149e75f395f51905f52600460056040516123aa92919061454b565b60405180910390a2505050979650505050505050565b6123c8612ddd565b80515f5b81811015612427576001600b8483815181106123ea576123ea614264565b60200260200101516040516123ff9190614566565b908152604051908190036020019020805491151560ff199092169190911790556001016123cc565b507f027b83cad653f54850fef6faa8c705f73a53e7f8de50a3a33ac1e0e3a5c0be81826040516119da919061457c565b5f546001600160a01b031633148061247957506003546001600160a01b031633145b6124c55760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c79205265676973747279206f7220536c617368696e674d677200000000604482015260640161099f565b5f8160ff161180156124db5750600d60ff821611155b6125205760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b604482015260640161099f565b61253e828260ff16600d81111561253957612539613c8f565b613542565b5050565b61254a612ddd565b6001600160a01b0381166125a05760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e61676572206164647265737300604482015260640161099f565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b0316331461263a5760405162461bcd60e51b815260206004820152601460248201527327b7363c9029b630b9b434b733a6b0b730b3b2b960611b604482015260640161099f565b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612684575f5ffd5b505af1158015612696573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee54282604051611b6191815260200190565b6126d4612ddd565b6001600160a01b0381161580159061270557505f828152600960205260409020546001600160a01b03828116911614155b8290612727576040516381c4951960e01b815260040161099f91815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb6991016119da565b612787612ddd565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ac7565b620f424080611007565b6127ce612ddd565b6001600160a01b038116158015906127f457506001546001600160a01b03828116911614155b8190612814576040516320252f0b60e01b815260040161099f9190613c26565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ac7908390613c26565b612868612ddd565b61287560208201826147eb565b63ffffffff1661288b60408301602084016147eb565b63ffffffff16101580156128b057505f6128a860208301836147eb565b63ffffffff16115b6128f05760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1a1c995cda1bdb19607a1b604482015260640161099f565b8060125f84600381111561290657612906613c8f565b600381111561291757612917613c8f565b815260208101919091526040015f206129319160026138e7565b5081600381111561294457612944613c8f565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa82604051611b619190614804565b61297b612ddd565b6001600160a01b0381166129a4575f604051631e4fbdf760e01b815260040161099f9190613c26565b610ae381612e7c565b5f818152600d602052604081205460ff16818160068111156129d1576129d1613c8f565b036129f657826001826040516337e1404160e01b815260040161099f93929190614610565b6005816006811115612a0a57612a0a613c8f565b03612a2b5760405163462c7bed60e01b81526004810184905260240161099f565b6006816006811115612a3f57612a3f613c8f565b03612a6057604051633de16e3560e11b81526004810184905260240161099f565b5f612a6b848361300b565b9350905080612a9057604051639f65d93560e01b81526004810185905260240161099f565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d811115612ad957612ad9613c8f565b0217905550835f5160206149e75f395f51905f52836006604051612afe92919061454b565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8385604051612b38929190614842565b60405180910390a25050919050565b612b4f612ddd565b6001600160a01b03811615801590612b7457505f546001600160a01b03828116911614155b8190612b94576040516375ac4eb760e11b815260040161099f9190613c26565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ac7908390613c26565b6001600160a01b0381165f90815260076020526040902054819060ff1615612c1b5760405163b29d459560e01b815260040161099f9190613c26565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ac7908390613c26565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b612ca06136aa565b610ae3816136cf565b8035612cec5760405162461bcd60e51b8152602060048201526012602482015271496e76616c696420444b472077696e646f7760701b604482015260640161099f565b5f816020013511612d385760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420636f6d707574652077696e646f7760501b604482015260640161099f565b5f816040013511612d875760405162461bcd60e51b8152602060048201526019602482015278496e76616c69642064656372797074696f6e2077696e646f7760381b604482015260640161099f565b80356013819055602080830135601481905560408085013560158190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ac7565b33612de6611c60565b6001600160a01b03161461194c573360405163118cdaa760e01b815260040161099f9190613c26565b6040516001600160a01b038481166024830152838116604483015260648201839052612e769186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506136d7565b50505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f818152600f602052604090205460609060ff16600181600d811115612f1457612f14613c8f565b1480612f315750600281600d811115612f2f57612f2f613c8f565b145b15612f69575f5b604051908082528060200260200182016040528015612f61578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015612fcf57506040513d5f823e601f3d908101601f19168201604052612fcc919081019061485d565b60015b612fd9575f612f38565b9392505050565b61300683846001600160a01b031663a9059cbb8585604051602401612e449291906148ec565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa158015613085573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a991906143c0565b905060018560068111156130bf576130bf613c8f565b1480156130cb57508042115b156130de5760018093509350505061318c565b60028560068111156130f2576130f2613c8f565b1480156130ff5750815142115b15613113576001600393509350505061318c565b600385600681111561312757613127613c8f565b1480156131375750816020015142115b1561314b576001600693509350505061318c565b600485600681111561315f5761315f613c8f565b14801561316f5750816040015142115b15613183576001600a93509350505061318c565b5f5f9350935050505b9250929050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa1580156131d8573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526131ff919081019061485d565b80515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b03169082900361329d576002546040516341489f1560e01b81526001600160a01b03909116906341489f159061326990889088908690600401614905565b5f604051808303815f87803b158015613280575f5ffd5b505af1158015613292573d5f5f3e3d5ffd5b505050505050505050565b825f0361333e575f858152601060205260409020546001600160a01b031680156132d5576132d56001600160a01b0383168285612fe0565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f159061330990899089908790600401614905565b5f604051808303815f87803b158015613320575f5ffd5b505af1158015613332573d5f5f3e3d5ffd5b50505050505050505050565b5f836001600160401b03811115613357576133576139d9565b604051908082528060200260200182016040528015613380578160200160208202803683370190505b5090505f61338e8585614935565b90505f805b868110156133cd57828482815181106133ae576133ae614264565b60209081029190910101526133c383836142ad565b9150600101613393565b505f6133d9828761429a565b905080156134165780846133ee60018a61429a565b815181106133fe576133fe614264565b6020026020010181815161341291906142ad565b9052505b600154613430906001600160a01b0387811691168861373a565b600154604051636ec640c760e11b81526001600160a01b039091169063dd8c818e906134649088908c908990600401614984565b5f604051808303815f87803b15801561347b575f5ffd5b505af115801561348d573d5f5f3e3d5ffd5b50506001546134ab92506001600160a01b038881169250165f61373a565b887fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a89866040516134dd9291906149b9565b60405180910390a26002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613519908c908c908a90600401614905565b5f604051808303815f87803b158015613530575f5ffd5b505af1158015610936573d5f5f3e3d5ffd5b5f828152600d602052604081205460ff169081600681111561356657613566613c8f565b0361358b57826001826040516337e1404160e01b815260040161099f93929190614610565b600581600681111561359f5761359f613c8f565b036135c05760405163462c7bed60e01b81526004810184905260240161099f565b60068160068111156135d4576135d4613c8f565b036135f557604051633de16e3560e11b81526004810184905260240161099f565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d81111561363e5761363e613c8f565b0217905550825f5160206149e75f395f51905f5282600660405161366392919061454b565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb828460405161369d929190614842565b60405180910390a2505050565b6136b26137ca565b61194c57604051631afcd79f60e31b815260040160405180910390fd5b61297b6136aa565b5f5f60205f8451602086015f885af1806136f6576040513d5f823e3d81fd5b50505f513d9150811561370d57806001141561371a565b6001600160a01b0384163b155b15612e765783604051635274afe760e01b815260040161099f9190613c26565b5f836001600160a01b031663095ea7b3848460405160240161375d9291906148ec565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061379684826137e3565b612e76576137c084856001600160a01b031663095ea7b3865f604051602401612e449291906148ec565b612e7684826136d7565b5f6137d3612c6e565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f519050828015613822575081156138145780600114613822565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001613854613983565b81525f602082018190526040820181905260608083018190526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b82600281019282156138d7579160200282015b828111156138d75782518255916020019190600101906138bc565b506138e39291506139a1565b5090565b6001830191839082156138d7579160200282015f5b8382111561394657833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026138fc565b80156139765782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613946565b50506138e39291506139a1565b60405180604001604052806002906020820280368337509192915050565b5b808211156138e3575f81556001016139a2565b6001600160a01b0381168114610ae3575f5ffd5b5f60608284031215611007575f5ffd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715613a1557613a156139d9565b604052919050565b5f6001600160401b03821115613a3557613a356139d9565b5060051b60200190565b5f82601f830112613a4e575f5ffd5b81356001600160401b03811115613a6757613a676139d9565b613a7a601f8201601f19166020016139ed565b818152846020838601011115613a8e575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f82601f830112613ab9575f5ffd5b8135613acc613ac782613a1d565b6139ed565b8082825260208201915060208360051b860101925085831115613aed575f5ffd5b602085015b83811015613b2d5780356001600160401b03811115613b0f575f5ffd5b613b1e886020838a0101613a3f565b84525060209283019201613af2565b5095945050505050565b5f5f5f5f5f5f5f5f610140898b031215613b4f575f5ffd5b8835613b5a816139b5565b97506020890135613b6a816139b5565b96506040890135613b7a816139b5565b95506060890135613b8a816139b5565b94506080890135613b9a816139b5565b935060a08901359250613bb08a60c08b016139c9565b91506101208901356001600160401b03811115613bcb575f5ffd5b613bd78b828c01613aaa565b9150509295985092959890939650565b5f60208284031215613bf7575f5ffd5b8135612fd9816139b5565b5f60208284031215613c12575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b803560048110613c48575f5ffd5b919050565b5f5f60408385031215613c5e575f5ffd5b613c6783613c3a565b946020939093013593505050565b5f60608284031215613c85575f5ffd5b612fd983836139c9565b634e487b7160e01b5f52602160045260245ffd5b600e8110613cb357613cb3613c8f565b9052565b60208101612c928284613ca3565b60048110613cb357613cb3613c8f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e8152613d13602082018f613cc5565b8c60408201528b6060820152613d2c608082018c613c19565b6101c060a08201525f613d436101c083018c613cd5565b82810360c0840152613d55818c613cd5565b9050613d6460e084018b613c19565b613d7261010084018a613c19565b8761012084015286610140840152828103610160840152613d938187613cd5565b915050613da4610180830185613c19565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015612e76578151845260209384019390910190600101613dc3565b805182525f6020820151613df96020850182613cc5565b50604082015160408401526060820151613e166060850182613dc0565b50608082015160a084015260a0820151613e3360c0850182613c19565b5060c082015161020060e0850152613e4f610200850182613cd5565b905060e0830151848203610100860152613e698282613cd5565b915050610100830151613e80610120860182613c19565b50610120830151613e95610140860182613c19565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152613ec78282613cd5565b9150506101a0830151613ede6101c0860182613c19565b506101c08301518015156101e0860152612f61565b602081525f612fd96020830184613de2565b5f60208284031215613f15575f5ffd5b81356001600160401b03811115613f2a575f5ffd5b613f3684828501613a3f565b949350505050565b5f60208284031215613f4e575f5ffd5b81356001600160401b03811115613f63575f5ffd5b82016101008185031215612fd9575f5ffd5b828152604060208201525f613f366040830184613de2565b5f60208284031215613f9d575f5ffd5b81356001600160401b03811115613fb2575f5ffd5b613f3684828501613aaa565b5f5f60408385031215613fcf575f5ffd5b823591506020830135613fe1816139b5565b809150509250929050565b5f5f60408385031215613ffd575f5ffd5b50508035926020909101359150565b81518152602080830151908201526040808301519082015260608101612c92565b821515815260408101612fd96020830184613ca3565b5f5f83601f840112614053575f5ffd5b5081356001600160401b03811115614069575f5ffd5b60208301915083602082850101111561318c575f5ffd5b5f5f5f5f5f60608688031215614094575f5ffd5b8535945060208601356001600160401b038111156140b0575f5ffd5b6140bc88828901614043565b90955093505060408601356001600160401b038111156140da575f5ffd5b6140e688828901614043565b969995985093965092949392505050565b5f5f5f5f5f5f5f6080888a03121561410d575f5ffd5b8735965060208801356001600160401b03811115614129575f5ffd5b6141358a828b01614043565b90975095505060408801356001600160401b03811115614153575f5ffd5b61415f8a828b01614043565b90955093505060608801356001600160401b0381111561417d575f5ffd5b6141898a828b01614043565b989b979a50959850939692959293505050565b5f5f604083850312156141ad575f5ffd5b82359150602083013560ff81168114613fe1575f5ffd5b60078110613cb357613cb3613c8f565b60208101612c9282846141c4565b5f5f606083850312156141f3575f5ffd5b6141fc83613c3a565b91508360608401111561420d575f5ffd5b50926020919091019150565b600181811c9082168061422d57607f821691505b60208210810361100757634e487b7160e01b5f52602260045260245ffd5b5f6020828403121561425b575f5ffd5b612fd982613c3a565b634e487b7160e01b5f52603260045260245ffd5b60208101612c928284613cc5565b634e487b7160e01b5f52601160045260245ffd5b81810381811115612c9257612c92614286565b80820180821115612c9257612c92614286565b5f600182016142d1576142d1614286565b5060010190565b5f5f8335601e198436030181126142ed575f5ffd5b8301803591506001600160401b03821115614306575f5ffd5b60200191503681900382131561318c575f5ffd5b8015158114610ae3575f5ffd5b5f60208284031215614337575f5ffd5b8135612fd98161431a565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b88815287602082015260a060408201525f61438960a08301888a614342565b828103606084015261439c818789614342565b905082810360808401526143b1818587614342565b9b9a5050505050505050505050565b5f602082840312156143d0575f5ffd5b5051919050565b601f82111561300657805f5260205f20601f840160051c810160208510156143fc5750805b601f840160051c820191505b8181101561441b575f8155600101614408565b5050505050565b5f19600383901b1c191660019190911b1790565b81516001600160401b0381111561444f5761444f6139d9565b6144638161445d8454614219565b846143d7565b6020601f821160018114614490575f831561447e5750848201515b6144888482614422565b85555061441b565b5f84815260208120601f198516915b828110156144bf578785015182556020948501946001909201910161449f565b50848210156144dc57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561452557815163ffffffff16835260209283019290910190600101614500565b505050949350505050565b5f60208284031215614540575f5ffd5b8151612fd98161431a565b6040810161455982856141c4565b612fd960208301846141c4565b5f82518060208501845e5f920191825250919050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156145d357603f198786030184526145be858351613cd5565b945060209384019391909101906001016145a2565b50929695505050505050565b6020808252601790820152764f6e6c79204369706865726e6f6465526567697374727960481b604082015260600190565b8381526060810161462460208301856141c4565b613f3660408301846141c4565b5f8151808452602084019350602083015f5b8281101561466a5781516001600160a01b0316865260209586019590910190600101614643565b5093949350505050565b848152836020820152608060408201525f6146926080830185614631565b905060018060a01b038316606083015295945050505050565b818382375f9101908152919050565b848152836020820152606060408201525f613822606083018486614342565b602081525f613f36602083018486614342565b6001600160401b03831115614703576147036139d9565b614717836147118354614219565b836143d7565b5f601f841160018114614743575f85156147315750838201355b61473b8682614422565b84555061441b565b5f83815260208120601f198716915b828110156147725786850135825560209485019460019092019101614752565b508682101561478e575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b858152606060208201525f6147b9606083018688614342565b82810360408401526147cc818587614342565b98975050505050505050565b803563ffffffff81168114613c48575f5ffd5b5f602082840312156147fb575f5ffd5b612fd9826147d8565b6040810181835f5b60028110156148395763ffffffff614823836147d8565b168352602092830192919091019060010161480c565b50505092915050565b6040810161485082856141c4565b612fd96020830184613ca3565b5f6020828403121561486d575f5ffd5b81516001600160401b03811115614882575f5ffd5b8201601f81018413614892575f5ffd5b80516148a0613ac782613a1d565b8082825260208201915060208360051b8501019250868311156148c1575f5ffd5b6020840193505b828410156138225783516148db816139b5565b8252602093840193909101906148c8565b6001600160a01b03929092168252602082015260400190565b838152606060208201525f61491d6060830185614631565b905060018060a01b0383166040830152949350505050565b5f8261494f57634e487b7160e01b5f52601260045260245ffd5b500490565b5f8151808452602084019350602083015f5b8281101561466a578151865260209586019590910190600101614966565b6001600160a01b03841681526060602082018190525f906149a790830185614631565b82810360408401526138228185614954565b604081525f6149cb6040830185614631565b82810360208401526149dd8185614954565b9594505050505056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 3e1d5d0334..b362a1f358 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -940,5 +940,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index 88373513c9..b55bf1b40f 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -624,6 +624,11 @@ "internalType": "bytes", "name": "proof", "type": "bytes" + }, + { + "internalType": "bytes", + "name": "foldProof", + "type": "bytes" } ], "name": "publishCommittee", @@ -782,5 +787,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index 432d009169..fb3cfe677d 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -1070,6 +1070,11 @@ "internalType": "bytes", "name": "proof", "type": "bytes" + }, + { + "internalType": "bytes", + "name": "foldProof", + "type": "bytes" } ], "name": "publishPlaintextOutput", @@ -1390,5 +1395,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 6d56ef23d5..7f8749fef3 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -954,5 +954,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-48efe0838d1e7fb2ef1a3cba330cb80744c9a50e" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index 522d8e156c..8e6b18cc2f 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -1012,6 +1012,11 @@ "internalType": "bytes", "name": "proof", "type": "bytes" + }, + { + "internalType": "bytes", + "name": "foldProof", + "type": "bytes" } ], "name": "publishCommittee", @@ -1242,30 +1247,30 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613cbe806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639a7a2ffc11610135578063dbb06c93116100b4578063f165053611610079578063f16505361461056a578063f2fde38b14610584578063f379b0df14610597578063f52fd803146105d1578063f6fc05d514610643575f5ffd5b8063dbb06c9314610517578063e59e469514610529578063e6745e131461053c578063e82f3b701461054f578063ebf0c71714610562575f5ffd5b8063c2b40ae4116100fa578063c2b40ae4146104a2578063c3a0ec30146104c1578063ca2869a0146104d2578063cd6dc687146104f1578063da881e5a14610504575f5ffd5b80639a7a2ffc146104245780639f0f874a14610460578063a016493014610469578063a8a4d69b1461047c578063bff232c11461048f575f5ffd5b806370e36bbe116101c15780638cb89ecb116101865780638cb89ecb146103c15780638d1ddfb1146103e05780638da5cb5b146103f65780638e5ce3ad146103fe5780639015d37114610411575f5ffd5b806370e36bbe14610346578063715018a6146103595780637c92f52414610361578063858142431461038e5780638a78bb15146103ae575f5ffd5b80632e7b716d116102075780632e7b716d146102d85780634d6861a6146102eb57806350e6d94c146102fe5780635d504776146103205780635e1d33bd14610333575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610294578063291a691b146102b5575b5f5ffd5b61025661025136600461317b565b61064c565b005b610256610266366004613196565b610798565b61027e610279366004613196565b6107db565b60405161028b91906131ad565b60405180910390f35b6102a76102a2366004613196565b61091d565b60405190815260200161028b565b6102c86102c33660046131f8565b610969565b604051901515815260200161028b565b6102c86102e636600461317b565b610b43565b6102c86102f9366004613196565b610bf6565b6102c861030c36600461317b565b60066020525f908152604090205460ff1681565b6102c861032e366004613231565b610c35565b6102566103413660046132a3565b610c79565b61025661035436600461317b565b610f59565b610256610fcf565b61037461036f366004613379565b610fe2565b6040805192835263ffffffff90911660208301520161028b565b6001546103a1906001600160a01b031681565b60405161028b91906133ae565b6102566103bc36600461317b565b611189565b6102a76103cf366004613196565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a7565b6103a16112c7565b600b546103a1906001600160a01b031681565b6102c861041f36600461317b565b6112f5565b61044a61043236600461317b565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028b565b6102a760035481565b61027e610477366004613196565b611312565b6102c861048a366004613231565b6113a8565b61025661049d36600461317b565b6113ec565b6102a76104b0366004613196565b60086020525f908152604090205481565b6001546001600160a01b03166103a1565b6102a76104e0366004613196565b5f9081526008602052604090205490565b6102566104ff3660046133c2565b61143d565b6102c8610512366004613196565b61159a565b5f546103a1906001600160a01b031681565b61025661053736600461317b565b6117cd565b61025661054a3660046133ec565b611845565b6102a761055d366004613196565b611a08565b6102a7611a39565b610572601481565b60405160ff909116815260200161028b565b61025661059236600461317b565b611a4b565b6004546105b39064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028b565b6106146105df366004613196565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028b949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a760025481565b6106546112c7565b6001600160a01b0316336001600160a01b0316148061067d57506001546001600160a01b031633145b61069a57604051632864c4e160e01b815260040160405180910390fd5b6106a3816112f5565b81906106cc576040516381e5828960e01b81526004016106c391906133ae565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906106fa9060049083611a85565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161072783613420565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107a0611d27565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602081905260408220600681015491810154606093919291816001600160401b0381111561081157610811613435565b60405190808252806020026020018201604052801561083a578160200160208202803683370190505b5090505f805b84811015610911576001866009015f8860060184815481106108645761086461345d565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205460ff16600281111561089c5761089c613449565b03610909578560060181815481106108b6576108b661345d565b905f5260205f20015f9054906101000a90046001600160a01b03168383815181106108e3576108e361345d565b6001600160a01b03909216602092830291909101909101528161090581613471565b9250505b600101610840565b50909695505050505050565b5f818152600a6020526040812081815460ff16600381111561094157610941613449565b0361095f57604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b031633146109945760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff1660038111156109b8576109b8613449565b146109d6576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a1d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a419190613489565b905080610a5460408601602087016134b3565b63ffffffff161115610a6c60408601602087016134b3565b829091610a9a576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106c3565b5050815460ff1916600190811783558201859055436002830155600354610ac190426134cc565b6003830155610ad5600583018560026130b2565b50610ade611a39565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610b2f928a928a92916134df565b60405180910390a250600195945050505050565b5f610b4d826112f5565b610b5857505f919050565b6001546001600160a01b0316610b81576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610bb19085906004016133ae565b602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf0919061353e565b92915050565b5f818152600a602052604081206001815460ff166003811115610c1b57610c1b613449565b14610c2857505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610c7157610c71613449565b149392505050565b610c81611d27565b5f878152600a602052604090206002815460ff166003811115610ca657610ca6613449565b14610cc457604051634f4b461f60e11b815260040160405180910390fd5b600481015415610ce75760405163632a22bb60e01b815260040160405180910390fd5b60068101548614610d305760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106c3565b5f610d3d83850185613655565b9150505f815111610d875760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106c3565b5f8160018351610d9791906136f8565b81518110610da757610da761345d565b60209081029190910101515f805460405163101bb4d760e21b8152600481018e905292935090916001600160a01b039091169063406ed35c906024015f60405180830381865afa158015610dfd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e2491908101906137dd565b61012081015160405163473b057f60e11b81529192506001600160a01b031690638e760afe90610e5a908990899060040161397c565b602060405180830381865afa158015610e75573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e999190613489565b5060048481018390555f8c815260096020526040808220859055905490516340a3b76160e11b81529182018d9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015610ef8575f5ffd5b505af1158015610f0a573d5f5f3e3d5ffd5b505050508a7ff7472ea3a028fe8a86ab1c9a3e2176b284c8c3a22675c101e0fa21c140b6678d8b8b8b8b604051610f44949392919061398f565b60405180910390a25050505050505050505050565b610f61611d27565b6001600160a01b038116610f885760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610fd7611d27565b610fe05f611d59565b565b600b545f9081906001600160a01b031633146110115760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff16600381111561103657611036613449565b1461105457604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff16600281111561109457611094613449565b146110a457600a01549150611181565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a82018054916110d883613420565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051611129929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b6111916112c7565b6001600160a01b0316336001600160a01b031614806111ba57506001546001600160a01b031633145b6111d757604051632864c4e160e01b815260040160405180910390fd5b6111e0816112f5565b6112c45760048054600160281b900464ffffffffff169061120a906001600160a01b038416611dc9565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff19909116179055600280549161125b83613471565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161078c565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a60205260409020600481015460609190611345576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561139b57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161137d575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff1660028111156113e3576113e3613449565b14159392505050565b6113f4611d27565b6001600160a01b03811661141b5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611446611f9f565b805490915060ff600160401b82041615906001600160401b03165f8115801561146c5750825b90505f826001600160401b031660011480156114875750303b155b905081158015611495575080155b156114b35760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156114dd57845460ff60401b1916600160401b1785555b6001600160a01b0387166115045760405163d92e233d60e01b815260040160405180910390fd5b61150d33611fc7565b61151960046014611fd8565b61152286610798565b61152a6112c7565b6001600160a01b0316876001600160a01b03161461154b5761154b87611a4b565b831561159157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156115be576115be613449565b036115dc57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156115f4576115f4613449565b1461161257604051631860f69960e31b815260040160405180910390fd5b8060030154421161163657604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061171b578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156116fc575f5ffd5b505af115801561170e573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a8301555f54604051631f3ea75d60e21b8152600481018690526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b158015611772575f5ffd5b505af1158015611784573d5f5f3e3d5ffd5b50505050837fed38c6266ebed7c01d311349a7fa67e0ef0f1d2f4760d60dbb34ca4799a2e132836006016040516117bb91906139f1565b60405180910390a25060019392505050565b6117d5611d27565b6001600160a01b0381166117fc5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff16600381111561186957611869613449565b0361188757604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561189f5761189f613449565b146118bd57604051631860f69960e31b815260040160405180910390fd5b80600301544211156118e257604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156119145760405163257309f160e11b815260040160405180910390fd5b61191d33610b43565b61193a5760405163149fbcfd60e11b815260040160405180910390fd5b611945338385612057565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff191660011790559091506119c490839083612228565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611a34576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611a4660046014612429565b905090565b611a53611d27565b6001600160a01b038116611a7c575f604051631e4fbdf760e01b81526004016106c391906133ae565b6112c481611d59565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611ac45760405162461bcd60e51b81526004016106c390613a34565b825464ffffffffff600160281b90910481169082168111611b225760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106c3565b825f5b81866001015f611b358488612522565b64ffffffffff1681526020019081526020015f20819055505f816001611b5b9190613a7e565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611b905750611d1f565b600185165f03611c57575f611baf83611baa886001613a97565b612522565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611c1091600401613ab4565b602060405180830381865af4158015611c2b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c4f9190613489565b935050611d0b565b5f611c6783611baa600189613ae4565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611cc891600401613ab4565b602060405180830381865af4158015611ce3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d079190613489565b9350505b50647fffffffff600194851c169301611b25565b505050505050565b33611d306112c7565b6001600160a01b031614610fe0573360405163118cdaa760e01b81526004016106c391906133ae565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611e185760405162461bcd60e51b81526004016106c390613a34565b825464ffffffffff90811690821610611e6b5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106c3565b611e76816001613a97565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611ead8487612522565b64ffffffffff16815260208101919091526040015f20556001831615611f98575f611edd82611baa600187613ae4565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611f3e91600401613ab4565b602060405180830381865af4158015611f59573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7d9190613489565b647fffffffff600195861c1694909350919091019050611e9d565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bf0565b611fcf61253f565b6112c481612564565b602060ff821611156120265760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106c3565b612037600160ff831681901b6136f8565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116120775760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166120a0576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916120d6916136f8565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561211d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121419190613489565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612194573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121b89190613489565b90505f81116121da5760405163aeaddff160e01b815260040160405180910390fd5b5f6121e58284613b01565b90505f81116122075760405163149fbcfd60e11b815260040160405180910390fd5b808611156115915760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156122a657508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612422565b5f5f90505f876008015f855f815481106122c2576122c261345d565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b845481101561234a575f896008015f87848154811061230c5761230c61345d565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612341578092508193505b506001016122eb565b5080861061235e575f945050505050612422565b5f886009015f8685815481106123765761237661345d565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156123b3576123b3613449565b0217905550868483815481106123cb576123cb61345d565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff161161247c5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106c3565b602060ff831611156124a05760405162461bcd60e51b81526004016106c390613b20565b8254600160281b900464ffffffffff16806124bf60ff85166002613c71565b64ffffffffff16101561250f5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106c3565b61251a84828561256c565b949350505050565b5f8161253560ff851663ffffffff613c8a565b6124229190613a97565b612547612634565b610fe057604051631afcd79f60e31b815260040160405180910390fd5b611a5361253f565b5f602060ff831611156125915760405162461bcd60e51b81526004016106c390613b20565b8264ffffffffff165f036125af576125a88261264d565b9050612422565b5f6125bb836001613a7e565b60ff166001600160401b038111156125d5576125d5613435565b6040519080825280602002602001820160405280156125fe578160200160208202803683370190505b50905061260d85858584612ce7565b808360ff16815181106126225761262261345d565b60200260200101519150509392505050565b5f61263d611f9f565b54600160401b900460ff16919050565b5f8160ff165f0361265f57505f919050565b8160ff1660010361269157507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036126c357507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff166003036126f557507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361272757507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361275957507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff1660060361278b57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036127bd57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff166008036127ef57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361282157507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361285357507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b0361288557507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036128b757507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d036128e957507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e0361291b57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f0361294d57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff1660100361297f57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff166011036129b157507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff166012036129e357507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612a1557507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612a4757507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612a7957507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612aab57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612add57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612b0f57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612b4157507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612b7357507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612ba557507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612bd757507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612c0957507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612c3b57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612c6d57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612c9f57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106c3565b602060ff83161115612d0b5760405162461bcd60e51b81526004016106c390613b20565b5f8364ffffffffff1611612d6f5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106c3565b5f612d7b600185613ae4565b9050600181165f03612dce57846001015f612d965f84612522565b64ffffffffff1681526020019081526020015f2054825f81518110612dbd57612dbd61345d565b602002602001018181525050612df6565b612dd75f61264d565b825f81518110612de957612de961345d565b6020026020010181815250505b5f5b8360ff168160ff161015611d1f57600182165f03612eee5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612e4a57612e4a61345d565b60200260200101518152602001612e608561264d565b8152506040518263ffffffff1660e01b8152600401612e7f9190613ab4565b602060405180830381865af4158015612e9a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ebe9190613489565b83612eca836001613a7e565b60ff1681518110612edd57612edd61345d565b60200260200101818152505061309f565b5f612efa826001613a7e565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115612f9c575f876001015f612f51856001612f409190613a7e565b60018864ffffffffff16901c612522565b64ffffffffff1681526020019081526020015f205490508085846001612f779190613a7e565b60ff1681518110612f8a57612f8a61345d565b6020026020010181815250505061309d565b5f876001015f612fb385600188611baa9190613ae4565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061300a5761300a61345d565b60200260200101518152506040518263ffffffff1660e01b81526004016130319190613ab4565b602060405180830381865af415801561304c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130709190613489565b8561307c856001613a7e565b60ff168151811061308f5761308f61345d565b602002602001018181525050505b505b647fffffffff600192831c169101612df8565b600183019183908215613143579160200282015f5b8382111561311157833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026130c7565b80156131415782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613111565b505b5061314f929150613153565b5090565b5b8082111561314f575f8155600101613154565b6001600160a01b03811681146112c4575f5ffd5b5f6020828403121561318b575f5ffd5b813561242281613167565b5f602082840312156131a6575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156131ed5783516001600160a01b03168352602093840193909201916001016131c6565b509095945050505050565b5f5f5f6080848603121561320a575f5ffd5b833592506020840135915060808401851015613224575f5ffd5b6040840190509250925092565b5f5f60408385031215613242575f5ffd5b82359150602083013561325481613167565b809150509250929050565b5f5f83601f84011261326f575f5ffd5b5081356001600160401b03811115613285575f5ffd5b60208301915083602082850101111561329c575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a0312156132b9575f5ffd5b8735965060208801356001600160401b038111156132d5575f5ffd5b8801601f81018a136132e5575f5ffd5b80356001600160401b038111156132fa575f5ffd5b8a60208260051b840101111561330e575f5ffd5b6020919091019650945060408801356001600160401b03811115613330575f5ffd5b61333c8a828b0161325f565b90955093505060608801356001600160401b0381111561335a575f5ffd5b6133668a828b0161325f565b989b979a50959850939692959293505050565b5f5f5f6060848603121561338b575f5ffd5b83359250602084013561339d81613167565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b5f5f604083850312156133d3575f5ffd5b82356133de81613167565b946020939093013593505050565b5f5f604083850312156133fd575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161342e5761342e61340c565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f600182016134825761348261340c565b5060010190565b5f60208284031215613499575f5ffd5b5051919050565b803563ffffffff81168114611a34575f5ffd5b5f602082840312156134c3575f5ffd5b612422826134a0565b80820180821115610bf057610bf061340c565b84815260a0810160208201855f5b600281101561351a5763ffffffff613504836134a0565b16835260209283019291909101906001016134ed565b50505060608201939093526080015292915050565b80518015158114611a34575f5ffd5b5f6020828403121561354e575f5ffd5b6124228261352f565b6040516101e081016001600160401b038111828210171561357a5761357a613435565b60405290565b604051601f8201601f191681016001600160401b03811182821017156135a8576135a8613435565b604052919050565b5f6001600160401b038211156135c8576135c8613435565b50601f01601f191660200190565b5f82601f8301126135e5575f5ffd5b81356001600160401b038111156135fe576135fe613435565b8060051b61360e60208201613580565b91825260208185018101929081019086841115613629575f5ffd5b6020860192505b8383101561364b578235825260209283019290910190613630565b9695505050505050565b5f5f60408385031215613666575f5ffd5b82356001600160401b0381111561367b575f5ffd5b8301601f8101851361368b575f5ffd5b803561369e613699826135b0565b613580565b8181528660208385010111156136b2575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b038111156136e2575f5ffd5b6136ee858286016135d6565b9150509250929050565b81810381811115610bf057610bf061340c565b805160048110611a34575f5ffd5b5f82601f830112613728575f5ffd5b604080519081016001600160401b038111828210171561374a5761374a613435565b8060405250806040840185811115613760575f5ffd5b845b8181101561377a578051835260209283019201613762565b509195945050505050565b8051611a3481613167565b5f82601f83011261379f575f5ffd5b81516137ad613699826135b0565b8181528460208386010111156137c1575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156137ed575f5ffd5b81516001600160401b03811115613802575f5ffd5b82016102008185031215613814575f5ffd5b61381c613557565b8151815261382c6020830161370b565b6020820152604082810151908201526138488560608401613719565b606082015260a0820151608082015261386360c08301613785565b60a082015260e08201516001600160401b03811115613880575f5ffd5b61388c86828501613790565b60c0830152506101008201516001600160401b038111156138ab575f5ffd5b6138b786828501613790565b60e0830152506138ca6101208301613785565b6101008201526138dd6101408301613785565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613913575f5ffd5b61391f86828501613790565b610180830152506139336101c08301613785565b6101a08201526139466101e0830161352f565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f61251a602083018486613954565b604080825281018490525f8560608301825b878110156139d15782356139b481613167565b6001600160a01b03168252602092830192909101906001016139a1565b5083810360208501526139e5818688613954565b98975050505050505050565b602080825282548282018190525f848152918220906040840190835b818110156131ed5783546001600160a01b0316835260019384019360209093019201613a0d565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610bf057610bf061340c565b64ffffffffff8181168382160190811115610bf057610bf061340c565b6040810181835f5b6002811015613adb578151835260209283019290910190600101613abc565b50505092915050565b64ffffffffff8281168282160390811115610bf057610bf061340c565b5f82613b1b57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b600184111561118157808504811115613b8257613b8261340c565b6001841615613b9057908102905b60019390931c928002613b67565b5f82613bac57506001610bf0565b81613bb857505f610bf0565b8160018114613bce5760028114613bd857613c0a565b6001915050610bf0565b60ff841115613be957613be961340c565b6001841b915064ffffffffff821115613c0457613c0461340c565b50610bf0565b5060208310610133831016604e8410600b8410161715613c42575081810a64ffffffffff811115613c3d57613c3d61340c565b610bf0565b613c5264ffffffffff8484613b63565b8064ffffffffff04821115613c6957613c6961340c565b029392505050565b5f61242264ffffffffff841664ffffffffff8416613b9e565b64ffffffffff8181168382160290811690818114613caa57613caa61340c565b509291505056fea164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639a7a2ffc11610135578063dbb06c93116100b4578063f165053611610079578063f16505361461056a578063f2fde38b14610584578063f379b0df14610597578063f52fd803146105d1578063f6fc05d514610643575f5ffd5b8063dbb06c9314610517578063e59e469514610529578063e6745e131461053c578063e82f3b701461054f578063ebf0c71714610562575f5ffd5b8063c2b40ae4116100fa578063c2b40ae4146104a2578063c3a0ec30146104c1578063ca2869a0146104d2578063cd6dc687146104f1578063da881e5a14610504575f5ffd5b80639a7a2ffc146104245780639f0f874a14610460578063a016493014610469578063a8a4d69b1461047c578063bff232c11461048f575f5ffd5b806370e36bbe116101c15780638cb89ecb116101865780638cb89ecb146103c15780638d1ddfb1146103e05780638da5cb5b146103f65780638e5ce3ad146103fe5780639015d37114610411575f5ffd5b806370e36bbe14610346578063715018a6146103595780637c92f52414610361578063858142431461038e5780638a78bb15146103ae575f5ffd5b80632e7b716d116102075780632e7b716d146102d85780634d6861a6146102eb57806350e6d94c146102fe5780635d504776146103205780635e1d33bd14610333575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610294578063291a691b146102b5575b5f5ffd5b61025661025136600461317b565b61064c565b005b610256610266366004613196565b610798565b61027e610279366004613196565b6107db565b60405161028b91906131ad565b60405180910390f35b6102a76102a2366004613196565b61091d565b60405190815260200161028b565b6102c86102c33660046131f8565b610969565b604051901515815260200161028b565b6102c86102e636600461317b565b610b43565b6102c86102f9366004613196565b610bf6565b6102c861030c36600461317b565b60066020525f908152604090205460ff1681565b6102c861032e366004613231565b610c35565b6102566103413660046132a3565b610c79565b61025661035436600461317b565b610f59565b610256610fcf565b61037461036f366004613379565b610fe2565b6040805192835263ffffffff90911660208301520161028b565b6001546103a1906001600160a01b031681565b60405161028b91906133ae565b6102566103bc36600461317b565b611189565b6102a76103cf366004613196565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a7565b6103a16112c7565b600b546103a1906001600160a01b031681565b6102c861041f36600461317b565b6112f5565b61044a61043236600461317b565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028b565b6102a760035481565b61027e610477366004613196565b611312565b6102c861048a366004613231565b6113a8565b61025661049d36600461317b565b6113ec565b6102a76104b0366004613196565b60086020525f908152604090205481565b6001546001600160a01b03166103a1565b6102a76104e0366004613196565b5f9081526008602052604090205490565b6102566104ff3660046133c2565b61143d565b6102c8610512366004613196565b61159a565b5f546103a1906001600160a01b031681565b61025661053736600461317b565b6117cd565b61025661054a3660046133ec565b611845565b6102a761055d366004613196565b611a08565b6102a7611a39565b610572601481565b60405160ff909116815260200161028b565b61025661059236600461317b565b611a4b565b6004546105b39064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028b565b6106146105df366004613196565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028b949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a760025481565b6106546112c7565b6001600160a01b0316336001600160a01b0316148061067d57506001546001600160a01b031633145b61069a57604051632864c4e160e01b815260040160405180910390fd5b6106a3816112f5565b81906106cc576040516381e5828960e01b81526004016106c391906133ae565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906106fa9060049083611a85565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161072783613420565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107a0611d27565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602081905260408220600681015491810154606093919291816001600160401b0381111561081157610811613435565b60405190808252806020026020018201604052801561083a578160200160208202803683370190505b5090505f805b84811015610911576001866009015f8860060184815481106108645761086461345d565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205460ff16600281111561089c5761089c613449565b03610909578560060181815481106108b6576108b661345d565b905f5260205f20015f9054906101000a90046001600160a01b03168383815181106108e3576108e361345d565b6001600160a01b03909216602092830291909101909101528161090581613471565b9250505b600101610840565b50909695505050505050565b5f818152600a6020526040812081815460ff16600381111561094157610941613449565b0361095f57604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b031633146109945760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff1660038111156109b8576109b8613449565b146109d6576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a1d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a419190613489565b905080610a5460408601602087016134b3565b63ffffffff161115610a6c60408601602087016134b3565b829091610a9a576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106c3565b5050815460ff1916600190811783558201859055436002830155600354610ac190426134cc565b6003830155610ad5600583018560026130b2565b50610ade611a39565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610b2f928a928a92916134df565b60405180910390a250600195945050505050565b5f610b4d826112f5565b610b5857505f919050565b6001546001600160a01b0316610b81576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610bb19085906004016133ae565b602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf0919061353e565b92915050565b5f818152600a602052604081206001815460ff166003811115610c1b57610c1b613449565b14610c2857505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610c7157610c71613449565b149392505050565b610c81611d27565b5f878152600a602052604090206002815460ff166003811115610ca657610ca6613449565b14610cc457604051634f4b461f60e11b815260040160405180910390fd5b600481015415610ce75760405163632a22bb60e01b815260040160405180910390fd5b60068101548614610d305760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106c3565b5f610d3d83850185613655565b9150505f815111610d875760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106c3565b5f8160018351610d9791906136f8565b81518110610da757610da761345d565b60209081029190910101515f805460405163101bb4d760e21b8152600481018e905292935090916001600160a01b039091169063406ed35c906024015f60405180830381865afa158015610dfd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e2491908101906137dd565b61012081015160405163473b057f60e11b81529192506001600160a01b031690638e760afe90610e5a908990899060040161397c565b602060405180830381865afa158015610e75573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e999190613489565b5060048481018390555f8c815260096020526040808220859055905490516340a3b76160e11b81529182018d9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015610ef8575f5ffd5b505af1158015610f0a573d5f5f3e3d5ffd5b505050508a7ff7472ea3a028fe8a86ab1c9a3e2176b284c8c3a22675c101e0fa21c140b6678d8b8b8b8b604051610f44949392919061398f565b60405180910390a25050505050505050505050565b610f61611d27565b6001600160a01b038116610f885760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610fd7611d27565b610fe05f611d59565b565b600b545f9081906001600160a01b031633146110115760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff16600381111561103657611036613449565b1461105457604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff16600281111561109457611094613449565b146110a457600a01549150611181565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a82018054916110d883613420565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051611129929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b6111916112c7565b6001600160a01b0316336001600160a01b031614806111ba57506001546001600160a01b031633145b6111d757604051632864c4e160e01b815260040160405180910390fd5b6111e0816112f5565b6112c45760048054600160281b900464ffffffffff169061120a906001600160a01b038416611dc9565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff19909116179055600280549161125b83613471565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161078c565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a60205260409020600481015460609190611345576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561139b57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161137d575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff1660028111156113e3576113e3613449565b14159392505050565b6113f4611d27565b6001600160a01b03811661141b5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611446611f9f565b805490915060ff600160401b82041615906001600160401b03165f8115801561146c5750825b90505f826001600160401b031660011480156114875750303b155b905081158015611495575080155b156114b35760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156114dd57845460ff60401b1916600160401b1785555b6001600160a01b0387166115045760405163d92e233d60e01b815260040160405180910390fd5b61150d33611fc7565b61151960046014611fd8565b61152286610798565b61152a6112c7565b6001600160a01b0316876001600160a01b03161461154b5761154b87611a4b565b831561159157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156115be576115be613449565b036115dc57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156115f4576115f4613449565b1461161257604051631860f69960e31b815260040160405180910390fd5b8060030154421161163657604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061171b578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156116fc575f5ffd5b505af115801561170e573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a8301555f54604051631f3ea75d60e21b8152600481018690526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b158015611772575f5ffd5b505af1158015611784573d5f5f3e3d5ffd5b50505050837fed38c6266ebed7c01d311349a7fa67e0ef0f1d2f4760d60dbb34ca4799a2e132836006016040516117bb91906139f1565b60405180910390a25060019392505050565b6117d5611d27565b6001600160a01b0381166117fc5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff16600381111561186957611869613449565b0361188757604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff16600381111561189f5761189f613449565b146118bd57604051631860f69960e31b815260040160405180910390fd5b80600301544211156118e257604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156119145760405163257309f160e11b815260040160405180910390fd5b61191d33610b43565b61193a5760405163149fbcfd60e11b815260040160405180910390fd5b611945338385612057565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff191660011790559091506119c490839083612228565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611a34576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611a4660046014612429565b905090565b611a53611d27565b6001600160a01b038116611a7c575f604051631e4fbdf760e01b81526004016106c391906133ae565b6112c481611d59565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611ac45760405162461bcd60e51b81526004016106c390613a34565b825464ffffffffff600160281b90910481169082168111611b225760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106c3565b825f5b81866001015f611b358488612522565b64ffffffffff1681526020019081526020015f20819055505f816001611b5b9190613a7e565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611b905750611d1f565b600185165f03611c57575f611baf83611baa886001613a97565b612522565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611c1091600401613ab4565b602060405180830381865af4158015611c2b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c4f9190613489565b935050611d0b565b5f611c6783611baa600189613ae4565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611cc891600401613ab4565b602060405180830381865af4158015611ce3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d079190613489565b9350505b50647fffffffff600194851c169301611b25565b505050505050565b33611d306112c7565b6001600160a01b031614610fe0573360405163118cdaa760e01b81526004016106c391906133ae565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611e185760405162461bcd60e51b81526004016106c390613a34565b825464ffffffffff90811690821610611e6b5760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106c3565b611e76816001613a97565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611ead8487612522565b64ffffffffff16815260208101919091526040015f20556001831615611f98575f611edd82611baa600187613ae4565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611f3e91600401613ab4565b602060405180830381865af4158015611f59573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7d9190613489565b647fffffffff600195861c1694909350919091019050611e9d565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bf0565b611fcf61253f565b6112c481612564565b602060ff821611156120265760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106c3565b612037600160ff831681901b6136f8565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116120775760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166120a0576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916120d6916136f8565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561211d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121419190613489565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612194573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121b89190613489565b90505f81116121da5760405163aeaddff160e01b815260040160405180910390fd5b5f6121e58284613b01565b90505f81116122075760405163149fbcfd60e11b815260040160405180910390fd5b808611156115915760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156122a657508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612422565b5f5f90505f876008015f855f815481106122c2576122c261345d565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b845481101561234a575f896008015f87848154811061230c5761230c61345d565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612341578092508193505b506001016122eb565b5080861061235e575f945050505050612422565b5f886009015f8685815481106123765761237661345d565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156123b3576123b3613449565b0217905550868483815481106123cb576123cb61345d565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff161161247c5760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106c3565b602060ff831611156124a05760405162461bcd60e51b81526004016106c390613b20565b8254600160281b900464ffffffffff16806124bf60ff85166002613c71565b64ffffffffff16101561250f5760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106c3565b61251a84828561256c565b949350505050565b5f8161253560ff851663ffffffff613c8a565b6124229190613a97565b612547612634565b610fe057604051631afcd79f60e31b815260040160405180910390fd5b611a5361253f565b5f602060ff831611156125915760405162461bcd60e51b81526004016106c390613b20565b8264ffffffffff165f036125af576125a88261264d565b9050612422565b5f6125bb836001613a7e565b60ff166001600160401b038111156125d5576125d5613435565b6040519080825280602002602001820160405280156125fe578160200160208202803683370190505b50905061260d85858584612ce7565b808360ff16815181106126225761262261345d565b60200260200101519150509392505050565b5f61263d611f9f565b54600160401b900460ff16919050565b5f8160ff165f0361265f57505f919050565b8160ff1660010361269157507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036126c357507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff166003036126f557507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361272757507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361275957507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff1660060361278b57507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036127bd57507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff166008036127ef57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361282157507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361285357507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b0361288557507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036128b757507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d036128e957507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e0361291b57507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f0361294d57507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff1660100361297f57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff166011036129b157507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff166012036129e357507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612a1557507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612a4757507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612a7957507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612aab57507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612add57507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612b0f57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612b4157507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612b7357507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612ba557507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612bd757507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612c0957507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612c3b57507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612c6d57507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612c9f57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106c3565b602060ff83161115612d0b5760405162461bcd60e51b81526004016106c390613b20565b5f8364ffffffffff1611612d6f5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106c3565b5f612d7b600185613ae4565b9050600181165f03612dce57846001015f612d965f84612522565b64ffffffffff1681526020019081526020015f2054825f81518110612dbd57612dbd61345d565b602002602001018181525050612df6565b612dd75f61264d565b825f81518110612de957612de961345d565b6020026020010181815250505b5f5b8360ff168160ff161015611d1f57600182165f03612eee5773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612e4a57612e4a61345d565b60200260200101518152602001612e608561264d565b8152506040518263ffffffff1660e01b8152600401612e7f9190613ab4565b602060405180830381865af4158015612e9a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ebe9190613489565b83612eca836001613a7e565b60ff1681518110612edd57612edd61345d565b60200260200101818152505061309f565b5f612efa826001613a7e565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115612f9c575f876001015f612f51856001612f409190613a7e565b60018864ffffffffff16901c612522565b64ffffffffff1681526020019081526020015f205490508085846001612f779190613a7e565b60ff1681518110612f8a57612f8a61345d565b6020026020010181815250505061309d565b5f876001015f612fb385600188611baa9190613ae4565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061300a5761300a61345d565b60200260200101518152506040518263ffffffff1660e01b81526004016130319190613ab4565b602060405180830381865af415801561304c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130709190613489565b8561307c856001613a7e565b60ff168151811061308f5761308f61345d565b602002602001018181525050505b505b647fffffffff600192831c169101612df8565b600183019183908215613143579160200282015f5b8382111561311157833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026130c7565b80156131415782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613111565b505b5061314f929150613153565b5090565b5b8082111561314f575f8155600101613154565b6001600160a01b03811681146112c4575f5ffd5b5f6020828403121561318b575f5ffd5b813561242281613167565b5f602082840312156131a6575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156131ed5783516001600160a01b03168352602093840193909201916001016131c6565b509095945050505050565b5f5f5f6080848603121561320a575f5ffd5b833592506020840135915060808401851015613224575f5ffd5b6040840190509250925092565b5f5f60408385031215613242575f5ffd5b82359150602083013561325481613167565b809150509250929050565b5f5f83601f84011261326f575f5ffd5b5081356001600160401b03811115613285575f5ffd5b60208301915083602082850101111561329c575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a0312156132b9575f5ffd5b8735965060208801356001600160401b038111156132d5575f5ffd5b8801601f81018a136132e5575f5ffd5b80356001600160401b038111156132fa575f5ffd5b8a60208260051b840101111561330e575f5ffd5b6020919091019650945060408801356001600160401b03811115613330575f5ffd5b61333c8a828b0161325f565b90955093505060608801356001600160401b0381111561335a575f5ffd5b6133668a828b0161325f565b989b979a50959850939692959293505050565b5f5f5f6060848603121561338b575f5ffd5b83359250602084013561339d81613167565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b5f5f604083850312156133d3575f5ffd5b82356133de81613167565b946020939093013593505050565b5f5f604083850312156133fd575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161342e5761342e61340c565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f600182016134825761348261340c565b5060010190565b5f60208284031215613499575f5ffd5b5051919050565b803563ffffffff81168114611a34575f5ffd5b5f602082840312156134c3575f5ffd5b612422826134a0565b80820180821115610bf057610bf061340c565b84815260a0810160208201855f5b600281101561351a5763ffffffff613504836134a0565b16835260209283019291909101906001016134ed565b50505060608201939093526080015292915050565b80518015158114611a34575f5ffd5b5f6020828403121561354e575f5ffd5b6124228261352f565b6040516101e081016001600160401b038111828210171561357a5761357a613435565b60405290565b604051601f8201601f191681016001600160401b03811182821017156135a8576135a8613435565b604052919050565b5f6001600160401b038211156135c8576135c8613435565b50601f01601f191660200190565b5f82601f8301126135e5575f5ffd5b81356001600160401b038111156135fe576135fe613435565b8060051b61360e60208201613580565b91825260208185018101929081019086841115613629575f5ffd5b6020860192505b8383101561364b578235825260209283019290910190613630565b9695505050505050565b5f5f60408385031215613666575f5ffd5b82356001600160401b0381111561367b575f5ffd5b8301601f8101851361368b575f5ffd5b803561369e613699826135b0565b613580565b8181528660208385010111156136b2575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b038111156136e2575f5ffd5b6136ee858286016135d6565b9150509250929050565b81810381811115610bf057610bf061340c565b805160048110611a34575f5ffd5b5f82601f830112613728575f5ffd5b604080519081016001600160401b038111828210171561374a5761374a613435565b8060405250806040840185811115613760575f5ffd5b845b8181101561377a578051835260209283019201613762565b509195945050505050565b8051611a3481613167565b5f82601f83011261379f575f5ffd5b81516137ad613699826135b0565b8181528460208386010111156137c1575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156137ed575f5ffd5b81516001600160401b03811115613802575f5ffd5b82016102008185031215613814575f5ffd5b61381c613557565b8151815261382c6020830161370b565b6020820152604082810151908201526138488560608401613719565b606082015260a0820151608082015261386360c08301613785565b60a082015260e08201516001600160401b03811115613880575f5ffd5b61388c86828501613790565b60c0830152506101008201516001600160401b038111156138ab575f5ffd5b6138b786828501613790565b60e0830152506138ca6101208301613785565b6101008201526138dd6101408301613785565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613913575f5ffd5b61391f86828501613790565b610180830152506139336101c08301613785565b6101a08201526139466101e0830161352f565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f61251a602083018486613954565b604080825281018490525f8560608301825b878110156139d15782356139b481613167565b6001600160a01b03168252602092830192909101906001016139a1565b5083810360208501526139e5818688613954565b98975050505050505050565b602080825282548282018190525f848152918220906040840190835b818110156131ed5783546001600160a01b0316835260019384019360209093019201613a0d565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610bf057610bf061340c565b64ffffffffff8181168382160190811115610bf057610bf061340c565b6040810181835f5b6002811015613adb578151835260209283019290910190600101613abc565b50505092915050565b64ffffffffff8281168282160390811115610bf057610bf061340c565b5f82613b1b57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b600184111561118157808504811115613b8257613b8261340c565b6001841615613b9057908102905b60019390931c928002613b67565b5f82613bac57506001610bf0565b81613bb857505f610bf0565b8160018114613bce5760028114613bd857613c0a565b6001915050610bf0565b60ff841115613be957613be961340c565b6001841b915064ffffffffff821115613c0457613c0461340c565b50610bf0565b5060208310610133831016604e8410600b8410161715613c42575081810a64ffffffffff811115613c3d57613c3d61340c565b610bf0565b613c5264ffffffffff8484613b63565b8064ffffffffff04821115613c6957613c6961340c565b029392505050565b5f61242264ffffffffff841664ffffffffff8416613b9e565b64ffffffffff8181168382160290811690818114613caa57613caa61340c565b509291505056fea164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613d22806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e14610571578063f2fde38b14610584578063f379b0df14610597578063f52fd803146105d1578063f6fc05d514610643575f5ffd5b8063e59e469514610516578063e6745e1314610529578063e82f3b701461053c578063ebf0c7171461054f578063f165053614610557575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104ae578063ca2869a0146104bf578063cd6dc687146104de578063da881e5a146104f1578063dbb06c9314610504575f5ffd5b80639f0f874a1461044d578063a016493014610456578063a8a4d69b14610469578063bff232c11461047c578063c2b40ae41461048f575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103cd5780638da5cb5b146103e35780638e5ce3ad146103eb5780639015d371146103fe5780639a7a2ffc14610411575f5ffd5b8063715018a6146103465780637c92f5241461034e578063858142431461037b5780638a78bb151461039b5780638cb89ecb146103ae575f5ffd5b80632e7b716d116102075780632e7b716d146102d85780634d6861a6146102eb57806350e6d94c146102fe5780635d5047761461032057806370e36bbe14610333575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610294578063291a691b146102b5575b5f5ffd5b610256610251366004613191565b61064c565b005b6102566102663660046131ac565b610798565b61027e6102793660046131ac565b6107db565b60405161028b91906131c3565b60405180910390f35b6102a76102a23660046131ac565b61091d565b60405190815260200161028b565b6102c86102c336600461320e565b610969565b604051901515815260200161028b565b6102c86102e6366004613191565b610b43565b6102c86102f93660046131ac565b610bf6565b6102c861030c366004613191565b60066020525f908152604090205460ff1681565b6102c861032e366004613247565b610c35565b610256610341366004613191565b610c79565b610256610cef565b61036161035c366004613275565b610d02565b6040805192835263ffffffff90911660208301520161028b565b60015461038e906001600160a01b031681565b60405161028b91906132aa565b6102566103a9366004613191565b610ea9565b6102a76103bc3660046131ac565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a7565b61038e610fe7565b600b5461038e906001600160a01b031681565b6102c861040c366004613191565b611015565b61043761041f366004613191565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028b565b6102a760035481565b61027e6104643660046131ac565b611032565b6102c8610477366004613247565b6110c8565b61025661048a366004613191565b61110c565b6102a761049d3660046131ac565b60086020525f908152604090205481565b6001546001600160a01b031661038e565b6102a76104cd3660046131ac565b5f9081526008602052604090205490565b6102566104ec3660046132be565b61115d565b6102c86104ff3660046131ac565b6112ba565b5f5461038e906001600160a01b031681565b610256610524366004613191565b6114ed565b6102566105373660046132e8565b611565565b6102a761054a3660046131ac565b611728565b6102a7611759565b61055f601481565b60405160ff909116815260200161028b565b61025661057f36600461334c565b61176b565b610256610592366004613191565b611a61565b6004546105b39064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028b565b6106146105df3660046131ac565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028b949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a760025481565b610654610fe7565b6001600160a01b0316336001600160a01b0316148061067d57506001546001600160a01b031633145b61069a57604051632864c4e160e01b815260040160405180910390fd5b6106a381611015565b81906106cc576040516381e5828960e01b81526004016106c391906132aa565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906106fa9060049083611a9b565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161072783613466565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107a0611d3d565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602081905260408220600681015491810154606093919291816001600160401b038111156108115761081161347b565b60405190808252806020026020018201604052801561083a578160200160208202803683370190505b5090505f805b84811015610911576001866009015f886006018481548110610864576108646134a3565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205460ff16600281111561089c5761089c61348f565b03610909578560060181815481106108b6576108b66134a3565b905f5260205f20015f9054906101000a90046001600160a01b03168383815181106108e3576108e36134a3565b6001600160a01b039092166020928302919091019091015281610905816134b7565b9250505b600101610840565b50909695505050505050565b5f818152600a6020526040812081815460ff1660038111156109415761094161348f565b0361095f57604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b031633146109945760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff1660038111156109b8576109b861348f565b146109d6576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a1d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a4191906134cf565b905080610a5460408601602087016134f9565b63ffffffff161115610a6c60408601602087016134f9565b829091610a9a576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106c3565b5050815460ff1916600190811783558201859055436002830155600354610ac19042613512565b6003830155610ad5600583018560026130c8565b50610ade611759565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610b2f928a928a9291613525565b60405180910390a250600195945050505050565b5f610b4d82611015565b610b5857505f919050565b6001546001600160a01b0316610b81576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610bb19085906004016132aa565b602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf09190613584565b92915050565b5f818152600a602052604081206001815460ff166003811115610c1b57610c1b61348f565b14610c2857505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610c7157610c7161348f565b149392505050565b610c81611d3d565b6001600160a01b038116610ca85760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610cf7611d3d565b610d005f611d6f565b565b600b545f9081906001600160a01b03163314610d315760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610d5657610d5661348f565b14610d7457604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610db457610db461348f565b14610dc457600a01549150610ea1565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610df883613466565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610e49929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610eb1610fe7565b6001600160a01b0316336001600160a01b03161480610eda57506001546001600160a01b031633145b610ef757604051632864c4e160e01b815260040160405180910390fd5b610f0081611015565b610fe45760048054600160281b900464ffffffffff1690610f2a906001600160a01b038416611ddf565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610f7b836134b7565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161078c565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a60205260409020600481015460609190611065576040516322e679e360e11b815260040160405180910390fd5b806006018054806020026020016040519081016040528092919081815260200182805480156110bb57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161109d575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff1660028111156111035761110361348f565b14159392505050565b611114611d3d565b6001600160a01b03811661113b5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611166611fb5565b805490915060ff600160401b82041615906001600160401b03165f8115801561118c5750825b90505f826001600160401b031660011480156111a75750303b155b9050811580156111b5575080155b156111d35760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156111fd57845460ff60401b1916600160401b1785555b6001600160a01b0387166112245760405163d92e233d60e01b815260040160405180910390fd5b61122d33611fdd565b61123960046014611fee565b61124286610798565b61124a610fe7565b6001600160a01b0316876001600160a01b03161461126b5761126b87611a61565b83156112b157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156112de576112de61348f565b036112fc57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156113145761131461348f565b1461133257604051631860f69960e31b815260040160405180910390fd5b8060030154421161135657604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061143b578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b15801561141c575f5ffd5b505af115801561142e573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a8301555f54604051631f3ea75d60e21b8152600481018690526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b50505050837fed38c6266ebed7c01d311349a7fa67e0ef0f1d2f4760d60dbb34ca4799a2e132836006016040516114db919061359d565b60405180910390a25060019392505050565b6114f5611d3d565b6001600160a01b03811661151c5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156115895761158961348f565b036115a757604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156115bf576115bf61348f565b146115dd57604051631860f69960e31b815260040160405180910390fd5b806003015442111561160257604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156116345760405163257309f160e11b815260040160405180910390fd5b61163d33610b43565b61165a5760405163149fbcfd60e11b815260040160405180910390fd5b61166533838561206d565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff191660011790559091506116e49083908361223e565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611754576040516322e679e360e11b815260040160405180910390fd5b919050565b5f6117666004601461243f565b905090565b611773611d3d565b5f898152600a602052604090206002815460ff1660038111156117985761179861348f565b146117b657604051634f4b461f60e11b815260040160405180910390fd5b6004810154156117d95760405163632a22bb60e01b815260040160405180910390fd5b600681015488146118225760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106c3565b5f61182f858701876136de565b9150505f8151116118795760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106c3565b5f81600183516118899190613781565b81518110611899576118996134a3565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016118e591815260200190565b5f60405180830381865afa1580156118ff573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526119269190810190613866565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611960908b908b908b908b90600401613a05565b602060405180830381865afa15801561197b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199f91906134cf565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b1580156119fe575f5ffd5b505af1158015611a10573d5f5f3e3d5ffd5b505050508c7ff7472ea3a028fe8a86ab1c9a3e2176b284c8c3a22675c101e0fa21c140b6678d8d8d8d8d604051611a4a9493929190613a36565b60405180910390a250505050505050505050505050565b611a69611d3d565b6001600160a01b038116611a92575f604051631e4fbdf760e01b81526004016106c391906132aa565b610fe481611d6f565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611ada5760405162461bcd60e51b81526004016106c390613a98565b825464ffffffffff600160281b90910481169082168111611b385760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106c3565b825f5b81866001015f611b4b8488612538565b64ffffffffff1681526020019081526020015f20819055505f816001611b719190613ae2565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611ba65750611d35565b600185165f03611c6d575f611bc583611bc0886001613afb565b612538565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611c2691600401613b18565b602060405180830381865af4158015611c41573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c6591906134cf565b935050611d21565b5f611c7d83611bc0600189613b48565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611cde91600401613b18565b602060405180830381865af4158015611cf9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d1d91906134cf565b9350505b50647fffffffff600194851c169301611b3b565b505050505050565b33611d46610fe7565b6001600160a01b031614610d00573360405163118cdaa760e01b81526004016106c391906132aa565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611e2e5760405162461bcd60e51b81526004016106c390613a98565b825464ffffffffff90811690821610611e815760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106c3565b611e8c816001613afb565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611ec38487612538565b64ffffffffff16815260208101919091526040015f20556001831615611fae575f611ef382611bc0600187613b48565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611f5491600401613b18565b602060405180830381865af4158015611f6f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f9391906134cf565b647fffffffff600195861c1694909350919091019050611eb3565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bf0565b611fe5612555565b610fe48161257a565b602060ff8216111561203c5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106c3565b61204d600160ff831681901b613781565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f821161208d5760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166120b6576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916120ec91613781565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612133573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061215791906134cf565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121ce91906134cf565b90505f81116121f05760405163aeaddff160e01b815260040160405180910390fd5b5f6121fb8284613b65565b90505f811161221d5760405163149fbcfd60e11b815260040160405180910390fd5b808611156112b15760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156122bc57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612438565b5f5f90505f876008015f855f815481106122d8576122d86134a3565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612360575f896008015f878481548110612322576123226134a3565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612357578092508193505b50600101612301565b50808610612374575f945050505050612438565b5f886009015f86858154811061238c5761238c6134a3565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156123c9576123c961348f565b0217905550868483815481106123e1576123e16134a3565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116124925760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106c3565b602060ff831611156124b65760405162461bcd60e51b81526004016106c390613b84565b8254600160281b900464ffffffffff16806124d560ff85166002613cd5565b64ffffffffff1610156125255760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106c3565b612530848285612582565b949350505050565b5f8161254b60ff851663ffffffff613cee565b6124389190613afb565b61255d61264a565b610d0057604051631afcd79f60e31b815260040160405180910390fd5b611a69612555565b5f602060ff831611156125a75760405162461bcd60e51b81526004016106c390613b84565b8264ffffffffff165f036125c5576125be82612663565b9050612438565b5f6125d1836001613ae2565b60ff166001600160401b038111156125eb576125eb61347b565b604051908082528060200260200182016040528015612614578160200160208202803683370190505b50905061262385858584612cfd565b808360ff1681518110612638576126386134a3565b60200260200101519150509392505050565b5f612653611fb5565b54600160401b900460ff16919050565b5f8160ff165f0361267557505f919050565b8160ff166001036126a757507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036126d957507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361270b57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361273d57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361276f57507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036127a157507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036127d357507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361280557507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361283757507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361286957507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b0361289b57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036128cd57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d036128ff57507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e0361293157507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f0361296357507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff1660100361299557507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff166011036129c757507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff166012036129f957507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612a2b57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612a5d57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612a8f57507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612ac157507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612af357507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612b2557507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612b5757507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612b8957507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612bbb57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612bed57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612c1f57507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612c5157507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612c8357507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612cb557507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106c3565b602060ff83161115612d215760405162461bcd60e51b81526004016106c390613b84565b5f8364ffffffffff1611612d855760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106c3565b5f612d91600185613b48565b9050600181165f03612de457846001015f612dac5f84612538565b64ffffffffff1681526020019081526020015f2054825f81518110612dd357612dd36134a3565b602002602001018181525050612e0c565b612ded5f612663565b825f81518110612dff57612dff6134a3565b6020026020010181815250505b5f5b8360ff168160ff161015611d3557600182165f03612f045773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612e6057612e606134a3565b60200260200101518152602001612e7685612663565b8152506040518263ffffffff1660e01b8152600401612e959190613b18565b602060405180830381865af4158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed491906134cf565b83612ee0836001613ae2565b60ff1681518110612ef357612ef36134a3565b6020026020010181815250506130b5565b5f612f10826001613ae2565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115612fb2575f876001015f612f67856001612f569190613ae2565b60018864ffffffffff16901c612538565b64ffffffffff1681526020019081526020015f205490508085846001612f8d9190613ae2565b60ff1681518110612fa057612fa06134a3565b602002602001018181525050506130b3565b5f876001015f612fc985600188611bc09190613b48565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff1681518110613020576130206134a3565b60200260200101518152506040518263ffffffff1660e01b81526004016130479190613b18565b602060405180830381865af4158015613062573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061308691906134cf565b85613092856001613ae2565b60ff16815181106130a5576130a56134a3565b602002602001018181525050505b505b647fffffffff600192831c169101612e0e565b600183019183908215613159579160200282015f5b8382111561312757833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026130dd565b80156131575782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613127565b505b50613165929150613169565b5090565b5b80821115613165575f815560010161316a565b6001600160a01b0381168114610fe4575f5ffd5b5f602082840312156131a1575f5ffd5b81356124388161317d565b5f602082840312156131bc575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156132035783516001600160a01b03168352602093840193909201916001016131dc565b509095945050505050565b5f5f5f60808486031215613220575f5ffd5b83359250602084013591506080840185101561323a575f5ffd5b6040840190509250925092565b5f5f60408385031215613258575f5ffd5b82359150602083013561326a8161317d565b809150509250929050565b5f5f5f60608486031215613287575f5ffd5b8335925060208401356132998161317d565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b5f5f604083850312156132cf575f5ffd5b82356132da8161317d565b946020939093013593505050565b5f5f604083850312156132f9575f5ffd5b50508035926020909101359150565b5f5f83601f840112613318575f5ffd5b5081356001600160401b0381111561332e575f5ffd5b602083019150836020828501011115613345575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c031215613364575f5ffd5b8935985060208a01356001600160401b03811115613380575f5ffd5b8a01601f81018c13613390575f5ffd5b80356001600160401b038111156133a5575f5ffd5b8c60208260051b84010111156133b9575f5ffd5b6020919091019850965060408a01356001600160401b038111156133db575f5ffd5b6133e78c828d01613308565b90975095505060608a01356001600160401b03811115613405575f5ffd5b6134118c828d01613308565b90955093505060808a01356001600160401b0381111561342f575f5ffd5b61343b8c828d01613308565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f8161347457613474613452565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f600182016134c8576134c8613452565b5060010190565b5f602082840312156134df575f5ffd5b5051919050565b803563ffffffff81168114611754575f5ffd5b5f60208284031215613509575f5ffd5b612438826134e6565b80820180821115610bf057610bf0613452565b84815260a0810160208201855f5b60028110156135605763ffffffff61354a836134e6565b1683526020928301929190910190600101613533565b50505060608201939093526080015292915050565b80518015158114611754575f5ffd5b5f60208284031215613594575f5ffd5b61243882613575565b602080825282548282018190525f848152918220906040840190835b818110156132035783546001600160a01b03168352600193840193602090930192016135b9565b6040516101e081016001600160401b03811182821017156136035761360361347b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156136315761363161347b565b604052919050565b5f6001600160401b038211156136515761365161347b565b50601f01601f191660200190565b5f82601f83011261366e575f5ffd5b81356001600160401b038111156136875761368761347b565b8060051b61369760208201613609565b918252602081850181019290810190868411156136b2575f5ffd5b6020860192505b838310156136d45782358252602092830192909101906136b9565b9695505050505050565b5f5f604083850312156136ef575f5ffd5b82356001600160401b03811115613704575f5ffd5b8301601f81018513613714575f5ffd5b803561372761372282613639565b613609565b81815286602083850101111561373b575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b0381111561376b575f5ffd5b6137778582860161365f565b9150509250929050565b81810381811115610bf057610bf0613452565b805160048110611754575f5ffd5b5f82601f8301126137b1575f5ffd5b604080519081016001600160401b03811182821017156137d3576137d361347b565b80604052508060408401858111156137e9575f5ffd5b845b818110156138035780518352602092830192016137eb565b509195945050505050565b80516117548161317d565b5f82601f830112613828575f5ffd5b815161383661372282613639565b81815284602083860101111561384a575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613876575f5ffd5b81516001600160401b0381111561388b575f5ffd5b8201610200818503121561389d575f5ffd5b6138a56135e0565b815181526138b560208301613794565b6020820152604082810151908201526138d185606084016137a2565b606082015260a082015160808201526138ec60c0830161380e565b60a082015260e08201516001600160401b03811115613909575f5ffd5b61391586828501613819565b60c0830152506101008201516001600160401b03811115613934575f5ffd5b61394086828501613819565b60e083015250613953610120830161380e565b610100820152613966610140830161380e565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b0381111561399c575f5ffd5b6139a886828501613819565b610180830152506139bc6101c0830161380e565b6101a08201526139cf6101e08301613575565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613a186040830186886139dd565b8281036020840152613a2b8185876139dd565b979650505050505050565b604080825281018490525f8560608301825b87811015613a78578235613a5b8161317d565b6001600160a01b0316825260209283019290910190600101613a48565b508381036020850152613a8c8186886139dd565b98975050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610bf057610bf0613452565b64ffffffffff8181168382160190811115610bf057610bf0613452565b6040810181835f5b6002811015613b3f578151835260209283019290910190600101613b20565b50505092915050565b64ffffffffff8281168282160390811115610bf057610bf0613452565b5f82613b7f57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610ea157808504811115613be657613be6613452565b6001841615613bf457908102905b60019390931c928002613bcb565b5f82613c1057506001610bf0565b81613c1c57505f610bf0565b8160018114613c325760028114613c3c57613c6e565b6001915050610bf0565b60ff841115613c4d57613c4d613452565b6001841b915064ffffffffff821115613c6857613c68613452565b50610bf0565b5060208310610133831016604e8410600b8410161715613ca6575081810a64ffffffffff811115613ca157613ca1613452565b610bf0565b613cb664ffffffffff8484613bc7565b8064ffffffffff04821115613ccd57613ccd613452565b029392505050565b5f61243864ffffffffff841664ffffffffff8416613c02565b64ffffffffff8181168382160290811690818114613d0e57613d0e613452565b509291505056fea164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639f0f874a11610135578063e59e4695116100b4578063f26ef74e11610079578063f26ef74e14610571578063f2fde38b14610584578063f379b0df14610597578063f52fd803146105d1578063f6fc05d514610643575f5ffd5b8063e59e469514610516578063e6745e1314610529578063e82f3b701461053c578063ebf0c7171461054f578063f165053614610557575f5ffd5b8063c3a0ec30116100fa578063c3a0ec30146104ae578063ca2869a0146104bf578063cd6dc687146104de578063da881e5a146104f1578063dbb06c9314610504575f5ffd5b80639f0f874a1461044d578063a016493014610456578063a8a4d69b14610469578063bff232c11461047c578063c2b40ae41461048f575f5ffd5b8063715018a6116101c15780638d1ddfb1116101865780638d1ddfb1146103cd5780638da5cb5b146103e35780638e5ce3ad146103eb5780639015d371146103fe5780639a7a2ffc14610411575f5ffd5b8063715018a6146103465780637c92f5241461034e578063858142431461037b5780638a78bb151461039b5780638cb89ecb146103ae575f5ffd5b80632e7b716d116102075780632e7b716d146102d85780634d6861a6146102eb57806350e6d94c146102fe5780635d5047761461032057806370e36bbe14610333575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780632800d82914610294578063291a691b146102b5575b5f5ffd5b610256610251366004613191565b61064c565b005b6102566102663660046131ac565b610798565b61027e6102793660046131ac565b6107db565b60405161028b91906131c3565b60405180910390f35b6102a76102a23660046131ac565b61091d565b60405190815260200161028b565b6102c86102c336600461320e565b610969565b604051901515815260200161028b565b6102c86102e6366004613191565b610b43565b6102c86102f93660046131ac565b610bf6565b6102c861030c366004613191565b60066020525f908152604090205460ff1681565b6102c861032e366004613247565b610c35565b610256610341366004613191565b610c79565b610256610cef565b61036161035c366004613275565b610d02565b6040805192835263ffffffff90911660208301520161028b565b60015461038e906001600160a01b031681565b60405161028b91906132aa565b6102566103a9366004613191565b610ea9565b6102a76103bc3660046131ac565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102a7565b61038e610fe7565b600b5461038e906001600160a01b031681565b6102c861040c366004613191565b611015565b61043761041f366004613191565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028b565b6102a760035481565b61027e6104643660046131ac565b611032565b6102c8610477366004613247565b6110c8565b61025661048a366004613191565b61110c565b6102a761049d3660046131ac565b60086020525f908152604090205481565b6001546001600160a01b031661038e565b6102a76104cd3660046131ac565b5f9081526008602052604090205490565b6102566104ec3660046132be565b61115d565b6102c86104ff3660046131ac565b6112ba565b5f5461038e906001600160a01b031681565b610256610524366004613191565b6114ed565b6102566105373660046132e8565b611565565b6102a761054a3660046131ac565b611728565b6102a7611759565b61055f601481565b60405160ff909116815260200161028b565b61025661057f36600461334c565b61176b565b610256610592366004613191565b611a61565b6004546105b39064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028b565b6106146105df3660046131ac565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028b949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102a760025481565b610654610fe7565b6001600160a01b0316336001600160a01b0316148061067d57506001546001600160a01b031633145b61069a57604051632864c4e160e01b815260040160405180910390fd5b6106a381611015565b81906106cc576040516381e5828960e01b81526004016106c391906132aa565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906106fa9060049083611a9b565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161072783613466565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107a0611d3d565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602081905260408220600681015491810154606093919291816001600160401b038111156108115761081161347b565b60405190808252806020026020018201604052801561083a578160200160208202803683370190505b5090505f805b84811015610911576001866009015f886006018481548110610864576108646134a3565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205460ff16600281111561089c5761089c61348f565b03610909578560060181815481106108b6576108b66134a3565b905f5260205f20015f9054906101000a90046001600160a01b03168383815181106108e3576108e36134a3565b6001600160a01b039092166020928302919091019091015281610905816134b7565b9250505b600101610840565b50909695505050505050565b5f818152600a6020526040812081815460ff1660038111156109415761094161348f565b0361095f57604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b031633146109945760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff1660038111156109b8576109b861348f565b146109d6576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610a1d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a4191906134cf565b905080610a5460408601602087016134f9565b63ffffffff161115610a6c60408601602087016134f9565b829091610a9a576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106c3565b5050815460ff1916600190811783558201859055436002830155600354610ac19042613512565b6003830155610ad5600583018560026130c8565b50610ade611759565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610b2f928a928a9291613525565b60405180910390a250600195945050505050565b5f610b4d82611015565b610b5857505f919050565b6001546001600160a01b0316610b81576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610bb19085906004016132aa565b602060405180830381865afa158015610bcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf09190613584565b92915050565b5f818152600a602052604081206001815460ff166003811115610c1b57610c1b61348f565b14610c2857505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff166002811115610c7157610c7161348f565b149392505050565b610c81611d3d565b6001600160a01b038116610ca85760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610cf7611d3d565b610d005f611d6f565b565b600b545f9081906001600160a01b03163314610d315760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610d5657610d5661348f565b14610d7457604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff166002811115610db457610db461348f565b14610dc457600a01549150610ea1565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a8201805491610df883613466565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610e49929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610eb1610fe7565b6001600160a01b0316336001600160a01b03161480610eda57506001546001600160a01b031633145b610ef757604051632864c4e160e01b815260040160405180910390fd5b610f0081611015565b610fe45760048054600160281b900464ffffffffff1690610f2a906001600160a01b038416611ddf565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491610f7b836134b7565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161078c565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a60205260409020600481015460609190611065576040516322e679e360e11b815260040160405180910390fd5b806006018054806020026020016040519081016040528092919081815260200182805480156110bb57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161109d575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff1660028111156111035761110361348f565b14159392505050565b611114611d3d565b6001600160a01b03811661113b5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611166611fb5565b805490915060ff600160401b82041615906001600160401b03165f8115801561118c5750825b90505f826001600160401b031660011480156111a75750303b155b9050811580156111b5575080155b156111d35760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156111fd57845460ff60401b1916600160401b1785555b6001600160a01b0387166112245760405163d92e233d60e01b815260040160405180910390fd5b61122d33611fdd565b61123960046014611fee565b61124286610798565b61124a610fe7565b6001600160a01b0316876001600160a01b03161461126b5761126b87611a61565b83156112b157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156112de576112de61348f565b036112fc57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156113145761131461348f565b1461133257604051631860f69960e31b815260040160405180910390fd5b8060030154421161135657604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061143b578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b15801561141c575f5ffd5b505af115801561142e573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a8301555f54604051631f3ea75d60e21b8152600481018690526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b158015611492575f5ffd5b505af11580156114a4573d5f5f3e3d5ffd5b50505050837fed38c6266ebed7c01d311349a7fa67e0ef0f1d2f4760d60dbb34ca4799a2e132836006016040516114db919061359d565b60405180910390a25060019392505050565b6114f5611d3d565b6001600160a01b03811661151c5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156115895761158961348f565b036115a757604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156115bf576115bf61348f565b146115dd57604051631860f69960e31b815260040160405180910390fd5b806003015442111561160257604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff16156116345760405163257309f160e11b815260040160405180910390fd5b61163d33610b43565b61165a5760405163149fbcfd60e11b815260040160405180910390fd5b61166533838561206d565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff191660011790559091506116e49083908361223e565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611754576040516322e679e360e11b815260040160405180910390fd5b919050565b5f6117666004601461243f565b905090565b611773611d3d565b5f898152600a602052604090206002815460ff1660038111156117985761179861348f565b146117b657604051634f4b461f60e11b815260040160405180910390fd5b6004810154156117d95760405163632a22bb60e01b815260040160405180910390fd5b600681015488146118225760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106c3565b5f61182f858701876136de565b9150505f8151116118795760405162461bcd60e51b815260206004820152601460248201527343353a206e6f207075626c696320696e7075747360601b60448201526064016106c3565b5f81600183516118899190613781565b81518110611899576118996134a3565b602002602001015190505f5f5f9054906101000a90046001600160a01b03166001600160a01b031663406ed35c8e6040518263ffffffff1660e01b81526004016118e591815260200190565b5f60405180830381865afa1580156118ff573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526119269190810190613866565b610120810151604051637bf41d7760e11b81529192506001600160a01b03169063f7e83aee90611960908b908b908b908b90600401613a05565b602060405180830381865afa15801561197b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199f91906134cf565b5060048085018390555f8e815260096020526040808220859055905490516340a3b76160e11b81529182018f9052602482018490526001600160a01b0316906381476ec2906044015f604051808303815f87803b1580156119fe575f5ffd5b505af1158015611a10573d5f5f3e3d5ffd5b505050508c7ff7472ea3a028fe8a86ab1c9a3e2176b284c8c3a22675c101e0fa21c140b6678d8d8d8d8d604051611a4a9493929190613a36565b60405180910390a250505050505050505050505050565b611a69611d3d565b6001600160a01b038116611a92575f604051631e4fbdf760e01b81526004016106c391906132aa565b610fe481611d6f565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611ada5760405162461bcd60e51b81526004016106c390613a98565b825464ffffffffff600160281b90910481169082168111611b385760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106c3565b825f5b81866001015f611b4b8488612538565b64ffffffffff1681526020019081526020015f20819055505f816001611b719190613ae2565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611ba65750611d35565b600185165f03611c6d575f611bc583611bc0886001613afb565b612538565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611c2691600401613b18565b602060405180830381865af4158015611c41573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c6591906134cf565b935050611d21565b5f611c7d83611bc0600189613b48565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611cde91600401613b18565b602060405180830381865af4158015611cf9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d1d91906134cf565b9350505b50647fffffffff600194851c169301611b3b565b505050505050565b33611d46610fe7565b6001600160a01b031614610d00573360405163118cdaa760e01b81526004016106c391906132aa565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611e2e5760405162461bcd60e51b81526004016106c390613a98565b825464ffffffffff90811690821610611e815760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106c3565b611e8c816001613afb565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f611ec38487612538565b64ffffffffff16815260208101919091526040015f20556001831615611fae575f611ef382611bc0600187613b48565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611f5491600401613b18565b602060405180830381865af4158015611f6f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f9391906134cf565b647fffffffff600195861c1694909350919091019050611eb3565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610bf0565b611fe5612555565b610fe48161257a565b602060ff8216111561203c5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106c3565b61204d600160ff831681901b613781565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f821161208d5760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166120b6576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916120ec91613781565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612133573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061215791906134cf565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121aa573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121ce91906134cf565b90505f81116121f05760405163aeaddff160e01b815260040160405180910390fd5b5f6121fb8284613b65565b90505f811161221d5760405163149fbcfd60e11b815260040160405180910390fd5b808611156112b15760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156122bc57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff1916821790559050612438565b5f5f90505f876008015f855f815481106122d8576122d86134a3565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612360575f896008015f878481548110612322576123226134a3565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905082811115612357578092508193505b50600101612301565b50808610612374575f945050505050612438565b5f886009015f86858154811061238c5761238c6134a3565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156123c9576123c961348f565b0217905550868483815481106123e1576123e16134a3565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116124925760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106c3565b602060ff831611156124b65760405162461bcd60e51b81526004016106c390613b84565b8254600160281b900464ffffffffff16806124d560ff85166002613cd5565b64ffffffffff1610156125255760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106c3565b612530848285612582565b949350505050565b5f8161254b60ff851663ffffffff613cee565b6124389190613afb565b61255d61264a565b610d0057604051631afcd79f60e31b815260040160405180910390fd5b611a69612555565b5f602060ff831611156125a75760405162461bcd60e51b81526004016106c390613b84565b8264ffffffffff165f036125c5576125be82612663565b9050612438565b5f6125d1836001613ae2565b60ff166001600160401b038111156125eb576125eb61347b565b604051908082528060200260200182016040528015612614578160200160208202803683370190505b50905061262385858584612cfd565b808360ff1681518110612638576126386134a3565b60200260200101519150509392505050565b5f612653611fb5565b54600160401b900460ff16919050565b5f8160ff165f0361267557505f919050565b8160ff166001036126a757507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036126d957507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361270b57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361273d57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361276f57507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036127a157507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036127d357507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361280557507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff1660090361283757507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361286957507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b0361289b57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c036128cd57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d036128ff57507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e0361293157507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f0361296357507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff1660100361299557507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff166011036129c757507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff166012036129f957507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612a2b57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612a5d57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612a8f57507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612ac157507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612af357507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612b2557507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612b5757507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612b8957507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612bbb57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612bed57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612c1f57507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612c5157507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612c8357507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612cb557507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106c3565b602060ff83161115612d215760405162461bcd60e51b81526004016106c390613b84565b5f8364ffffffffff1611612d855760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106c3565b5f612d91600185613b48565b9050600181165f03612de457846001015f612dac5f84612538565b64ffffffffff1681526020019081526020015f2054825f81518110612dd357612dd36134a3565b602002602001018181525050612e0c565b612ded5f612663565b825f81518110612dff57612dff6134a3565b6020026020010181815250505b5f5b8360ff168160ff161015611d3557600182165f03612f045773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612e6057612e606134a3565b60200260200101518152602001612e7685612663565b8152506040518263ffffffff1660e01b8152600401612e959190613b18565b602060405180830381865af4158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed491906134cf565b83612ee0836001613ae2565b60ff1681518110612ef357612ef36134a3565b6020026020010181815250506130b5565b5f612f10826001613ae2565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115612fb2575f876001015f612f67856001612f569190613ae2565b60018864ffffffffff16901c612538565b64ffffffffff1681526020019081526020015f205490508085846001612f8d9190613ae2565b60ff1681518110612fa057612fa06134a3565b602002602001018181525050506130b3565b5f876001015f612fc985600188611bc09190613b48565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff1681518110613020576130206134a3565b60200260200101518152506040518263ffffffff1660e01b81526004016130479190613b18565b602060405180830381865af4158015613062573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061308691906134cf565b85613092856001613ae2565b60ff16815181106130a5576130a56134a3565b602002602001018181525050505b505b647fffffffff600192831c169101612e0e565b600183019183908215613159579160200282015f5b8382111561312757833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026130dd565b80156131575782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613127565b505b50613165929150613169565b5090565b5b80821115613165575f815560010161316a565b6001600160a01b0381168114610fe4575f5ffd5b5f602082840312156131a1575f5ffd5b81356124388161317d565b5f602082840312156131bc575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156132035783516001600160a01b03168352602093840193909201916001016131dc565b509095945050505050565b5f5f5f60808486031215613220575f5ffd5b83359250602084013591506080840185101561323a575f5ffd5b6040840190509250925092565b5f5f60408385031215613258575f5ffd5b82359150602083013561326a8161317d565b809150509250929050565b5f5f5f60608486031215613287575f5ffd5b8335925060208401356132998161317d565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b5f5f604083850312156132cf575f5ffd5b82356132da8161317d565b946020939093013593505050565b5f5f604083850312156132f9575f5ffd5b50508035926020909101359150565b5f5f83601f840112613318575f5ffd5b5081356001600160401b0381111561332e575f5ffd5b602083019150836020828501011115613345575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f60a08a8c031215613364575f5ffd5b8935985060208a01356001600160401b03811115613380575f5ffd5b8a01601f81018c13613390575f5ffd5b80356001600160401b038111156133a5575f5ffd5b8c60208260051b84010111156133b9575f5ffd5b6020919091019850965060408a01356001600160401b038111156133db575f5ffd5b6133e78c828d01613308565b90975095505060608a01356001600160401b03811115613405575f5ffd5b6134118c828d01613308565b90955093505060808a01356001600160401b0381111561342f575f5ffd5b61343b8c828d01613308565b915080935050809150509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f8161347457613474613452565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f600182016134c8576134c8613452565b5060010190565b5f602082840312156134df575f5ffd5b5051919050565b803563ffffffff81168114611754575f5ffd5b5f60208284031215613509575f5ffd5b612438826134e6565b80820180821115610bf057610bf0613452565b84815260a0810160208201855f5b60028110156135605763ffffffff61354a836134e6565b1683526020928301929190910190600101613533565b50505060608201939093526080015292915050565b80518015158114611754575f5ffd5b5f60208284031215613594575f5ffd5b61243882613575565b602080825282548282018190525f848152918220906040840190835b818110156132035783546001600160a01b03168352600193840193602090930192016135b9565b6040516101e081016001600160401b03811182821017156136035761360361347b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156136315761363161347b565b604052919050565b5f6001600160401b038211156136515761365161347b565b50601f01601f191660200190565b5f82601f83011261366e575f5ffd5b81356001600160401b038111156136875761368761347b565b8060051b61369760208201613609565b918252602081850181019290810190868411156136b2575f5ffd5b6020860192505b838310156136d45782358252602092830192909101906136b9565b9695505050505050565b5f5f604083850312156136ef575f5ffd5b82356001600160401b03811115613704575f5ffd5b8301601f81018513613714575f5ffd5b803561372761372282613639565b613609565b81815286602083850101111561373b575f5ffd5b816020840160208301375f6020838301015280945050505060208301356001600160401b0381111561376b575f5ffd5b6137778582860161365f565b9150509250929050565b81810381811115610bf057610bf0613452565b805160048110611754575f5ffd5b5f82601f8301126137b1575f5ffd5b604080519081016001600160401b03811182821017156137d3576137d361347b565b80604052508060408401858111156137e9575f5ffd5b845b818110156138035780518352602092830192016137eb565b509195945050505050565b80516117548161317d565b5f82601f830112613828575f5ffd5b815161383661372282613639565b81815284602083860101111561384a575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f60208284031215613876575f5ffd5b81516001600160401b0381111561388b575f5ffd5b8201610200818503121561389d575f5ffd5b6138a56135e0565b815181526138b560208301613794565b6020820152604082810151908201526138d185606084016137a2565b606082015260a082015160808201526138ec60c0830161380e565b60a082015260e08201516001600160401b03811115613909575f5ffd5b61391586828501613819565b60c0830152506101008201516001600160401b03811115613934575f5ffd5b61394086828501613819565b60e083015250613953610120830161380e565b610100820152613966610140830161380e565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b0381111561399c575f5ffd5b6139a886828501613819565b610180830152506139bc6101c0830161380e565b6101a08201526139cf6101e08301613575565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f613a186040830186886139dd565b8281036020840152613a2b8185876139dd565b979650505050505050565b604080825281018490525f8560608301825b87811015613a78578235613a5b8161317d565b6001600160a01b0316825260209283019290910190600101613a48565b508381036020850152613a8c8186886139dd565b98975050505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610bf057610bf0613452565b64ffffffffff8181168382160190811115610bf057610bf0613452565b6040810181835f5b6002811015613b3f578151835260209283019290910190600101613b20565b50505092915050565b64ffffffffff8281168282160390811115610bf057610bf0613452565b5f82613b7f57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610ea157808504811115613be657613be6613452565b6001841615613bf457908102905b60019390931c928002613bcb565b5f82613c1057506001610bf0565b81613c1c57505f610bf0565b8160018114613c325760028114613c3c57613c6e565b6001915050610bf0565b60ff841115613c4d57613c4d613452565b6001841b915064ffffffffff821115613c6857613c68613452565b50610bf0565b5060208310610133831016604e8410600b8410161715613ca6575081810a64ffffffffff811115613ca157613ca1613452565b610bf0565b613cb664ffffffffff8484613bc7565b8064ffffffffff04821115613ccd57613ccd613452565b029392505050565b5f61243864ffffffffff841664ffffffffff8416613c02565b64ffffffffff8181168382160290811690818114613d0e57613d0e613452565b509291505056fea164736f6c634300081c000a", "linkReferences": { "npm/poseidon-solidity@0.0.5/PoseidonT3.sol": { "PoseidonT3": [ { "length": 20, - "start": 7360 + "start": 7382 }, { "length": 20, - "start": 7544 + "start": 7566 }, { "length": 20, - "start": 8174 + "start": 8196 }, { "length": 20, - "start": 12008 + "start": 12030 }, { "length": 20, - "start": 12450 + "start": 12472 } ] } @@ -1275,28 +1280,28 @@ "PoseidonT3": [ { "length": 20, - "start": 7146 + "start": 7168 }, { "length": 20, - "start": 7330 + "start": 7352 }, { "length": 20, - "start": 7960 + "start": 7982 }, { "length": 20, - "start": 11794 + "start": 11816 }, { "length": 20, - "start": 12236 + "start": 12258 } ] } }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-9ac09828abf2959f97031765d7270708a52260d9" + "buildInfoId": "solc-0_8_28-561f4408bcfee777a1360e3f4f4b4e2d1bea7249" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index ed13d1f775..e547864e3a 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -452,7 +452,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { function publishPlaintextOutput( uint256 e3Id, bytes calldata plaintextOutput, - bytes calldata proof + bytes calldata proof, + bytes calldata foldProof ) external returns (bool success) { E3 memory e3 = getE3(e3Id); @@ -477,7 +478,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { (success) = e3.decryptionVerifier.verify( keccak256(plaintextOutput), - proof + proof, + foldProof ); require(success, InvalidOutput(plaintextOutput)); diff --git a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol index 9bedd26d02..f6d4f0a5e5 100644 --- a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol @@ -203,11 +203,13 @@ interface ICiphernodeRegistry { /// @param nodes Array of ciphernode addresses selected for the committee. /// @param publicKey The public key generated by the given committee. /// @param proof C5 proof; ABI-encoded (bytes rawProof, bytes32[] publicInputs). Last input is aggregate commitment. + /// @param foldProof Optional fold proof ABI-encoded (bytes, bytes32[]); empty to skip. function publishCommittee( uint256 e3Id, address[] calldata nodes, bytes calldata publicKey, - bytes calldata proof + bytes calldata proof, + bytes calldata foldProof ) external; /// @notice This function should be called by the Enclave contract to get the public key of a committee. diff --git a/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol b/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol index 665cf3de0b..2f4b78322c 100644 --- a/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol @@ -14,10 +14,12 @@ interface IDecryptionVerifier { /// @notice Verify the decryption of a computation output /// @dev This function is called by the Enclave contract when plaintext output is published /// @param plaintextOutputHash The keccak256 hash of the plaintext output to be verified - /// @param proof ABI encoded proof of the decryption validity + /// @param proof ABI-encoded (bytes, bytes32[]) for C7. + /// @param foldProof ABI-encoded fold proof (bytes, bytes32[]) or empty to skip. /// @return success Whether the plaintextOutputHash was successfully verified function verify( bytes32 plaintextOutputHash, - bytes memory proof + bytes memory proof, + bytes memory foldProof ) external view returns (bool success); } diff --git a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol index b4edc054ca..160e957b15 100644 --- a/packages/enclave-contracts/contracts/interfaces/IEnclave.sol +++ b/packages/enclave-contracts/contracts/interfaces/IEnclave.sol @@ -281,11 +281,13 @@ interface IEnclave { /// @dev This function MUST emit the PlaintextOutputPublished event. /// @param e3Id ID of the E3. /// @param plaintextOutput ABI encoded plaintext output. - /// @param proof ABI encoded data to verify the plaintextOutput. + /// @param proof ABI encoded data to verify the plaintextOutput (C7). + /// @param foldProof Optional fold proof ABI-encoded (bytes, bytes32[]); empty to skip. function publishPlaintextOutput( uint256 e3Id, bytes calldata plaintextOutput, - bytes calldata proof + bytes calldata proof, + bytes calldata foldProof ) external returns (bool success); //////////////////////////////////////////////////////////// diff --git a/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol b/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol index 1eebbc5ebf..41c8561ad4 100644 --- a/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol +++ b/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol @@ -12,10 +12,12 @@ pragma solidity >=0.8.27; */ interface IPkVerifier { /// @notice Verify a C5 (pk_aggregation) proof and return the aggregate commitment. - /// @param proof ABI-encoded (bytes rawProof, bytes32[] publicInputs) + /// @param proof ABI-encoded (bytes rawProof, bytes32[] publicInputs). + /// @param foldProof ABI-encoded fold proof (bytes, bytes32[]) or empty to skip. /// @return pkCommitment The aggregate public key commitment (last public input). /// @dev Reverts if the proof is invalid. function verify( - bytes memory proof + bytes memory proof, + bytes memory foldProof ) external view returns (bytes32 pkCommitment); } diff --git a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol index bb5f8ccb85..99400fc357 100644 --- a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol +++ b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol @@ -279,11 +279,13 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { /// @param nodes Array of ciphernode addresses selected for the committee /// @param publicKey Aggregated public key of the committee /// @param proof C5 proof; aggregate commitment extracted as last public input + /// @param foldProof Optional ABI-encoded fold proof (bytes, bytes32[]); empty to skip function publishCommittee( uint256 e3Id, address[] calldata nodes, bytes calldata publicKey, - bytes calldata proof + bytes calldata proof, + bytes calldata foldProof ) external onlyOwner { Committee storage c = committees[e3Id]; @@ -302,7 +304,7 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { bytes32 publicKeyHash = publicInputs[publicInputs.length - 1]; E3 memory e3 = enclave.getE3(e3Id); - e3.pkVerifier.verify(proof); + e3.pkVerifier.verify(proof, foldProof); c.publicKey = publicKeyHash; publicKeyHashes[e3Id] = publicKeyHash; diff --git a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol index cd8c8e4ca6..c7fe477c34 100644 --- a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol @@ -70,6 +70,7 @@ contract MockCiphernodeRegistry is ICiphernodeRegistry { uint256, address[] calldata, bytes calldata, + bytes calldata, bytes calldata ) external pure {} // solhint-disable-line no-empty-blocks @@ -207,6 +208,7 @@ contract MockCiphernodeRegistryEmptyKey is ICiphernodeRegistry { uint256, address[] calldata, bytes calldata, + bytes calldata, bytes calldata ) external pure {} // solhint-disable-line no-empty-blocks diff --git a/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol b/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol index 54873cb636..65c868ca5b 100644 --- a/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol @@ -10,7 +10,8 @@ import { IDecryptionVerifier } from "../interfaces/IDecryptionVerifier.sol"; contract MockDecryptionVerifier is IDecryptionVerifier { function verify( bytes32, - bytes memory data + bytes memory data, + bytes memory /* foldProof */ ) external pure returns (bool success) { data; diff --git a/packages/enclave-contracts/contracts/test/MockPkVerifier.sol b/packages/enclave-contracts/contracts/test/MockPkVerifier.sol index 7189c4fbce..d7a57fe40f 100644 --- a/packages/enclave-contracts/contracts/test/MockPkVerifier.sol +++ b/packages/enclave-contracts/contracts/test/MockPkVerifier.sol @@ -9,7 +9,8 @@ import { IPkVerifier } from "../interfaces/IPkVerifier.sol"; contract MockPkVerifier is IPkVerifier { function verify( - bytes memory proof + bytes memory proof, + bytes memory /* foldProof */ ) external pure returns (bytes32 pkCommitment) { (, bytes32[] memory publicInputs) = abi.decode( proof, diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol index 9168dac996..3f762f0dc7 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol @@ -14,6 +14,8 @@ import { ICircuitVerifier } from "../../interfaces/ICircuitVerifier.sol"; * (decrypted_shares_aggregation) proofs on-chain by delegating to the Honk * ThresholdDecryptedSharesAggregationVerifier and validating that the * plaintext extracted from public inputs matches the claimed hash. + * Optional `foldProof` is ABI-encoded (bytes, bytes32[]) for RecursiveAggregationFoldVerifier + * (C6 cross-node fold); pass empty bytes to skip. * @dev Use this verifier when the Enclave is configured with encryptionSchemeId * keccak256("fhe.rs:BFV"). Other encryption schemes will have their own verifiers. */ @@ -23,15 +25,18 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { uint256 constant MESSAGE_COEFFS_COUNT = 100; ICircuitVerifier public immutable circuitVerifier; + ICircuitVerifier public immutable foldVerifier; - constructor(address _circuitVerifier) { + constructor(address _circuitVerifier, address _foldVerifier) { circuitVerifier = ICircuitVerifier(_circuitVerifier); + foldVerifier = ICircuitVerifier(_foldVerifier); } /// @inheritdoc IDecryptionVerifier function verify( bytes32 plaintextOutputHash, - bytes memory proof + bytes memory proof, + bytes memory foldProof ) external view override returns (bool success) { (bytes memory rawProof, bytes32[] memory publicInputs) = abi.decode( proof, @@ -50,9 +55,28 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { return false; } + if (!_verifyFold(foldProof)) { + return false; + } + return true; } + function _verifyFold(bytes memory foldProof) internal view returns (bool) { + if (foldProof.length == 0) { + return true; + } + + (bytes memory foldRawProof, bytes32[] memory foldPublicInputs) = abi + .decode(foldProof, (bytes, bytes32[])); + + if (foldRawProof.length == 0 || foldPublicInputs.length == 0) { + return false; + } + + return foldVerifier.verify(foldRawProof, foldPublicInputs); + } + function _verifyPlaintextHash( bytes32[] memory publicInputs, bytes32 plaintextOutputHash diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol index b9b55fb245..2ed2c7c51b 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol @@ -12,18 +12,23 @@ import { ICircuitVerifier } from "../../interfaces/ICircuitVerifier.sol"; * @title BfvPkVerifier * @notice Verifies C5 (pk_aggregation) proofs on-chain. Delegates to the Honk * ThresholdPkAggregationVerifier and returns the aggregate commitment from public inputs. + * Optional `foldProof` is ABI-encoded (bytes, bytes32[]) for RecursiveAggregationFoldVerifier + * (DKG cross-node fold); pass empty bytes to skip. * @dev Use with encryptionSchemeId keccak256("fhe.rs:BFV"). Commitment count is enforced by the VK. */ contract BfvPkVerifier is IPkVerifier { ICircuitVerifier public immutable circuitVerifier; + ICircuitVerifier public immutable foldVerifier; - constructor(address _circuitVerifier) { + constructor(address _circuitVerifier, address _foldVerifier) { circuitVerifier = ICircuitVerifier(_circuitVerifier); + foldVerifier = ICircuitVerifier(_foldVerifier); } /// @inheritdoc IPkVerifier function verify( - bytes memory proof + bytes memory proof, + bytes memory foldProof ) external view override returns (bytes32 pkCommitment) { (bytes memory rawProof, bytes32[] memory publicInputs) = abi.decode( proof, @@ -36,6 +41,22 @@ contract BfvPkVerifier is IPkVerifier { "BfvPkVerifier: invalid proof" ); + _verifyFold(foldProof); + return publicInputs[publicInputs.length - 1]; } + + function _verifyFold(bytes memory foldProof) internal view { + if (foldProof.length == 0) { + return; + } + + (bytes memory foldRawProof, bytes32[] memory foldPublicInputs) = abi + .decode(foldProof, (bytes, bytes32[])); + + require( + foldVerifier.verify(foldRawProof, foldPublicInputs), + "BfvPkVerifier: invalid fold proof" + ); + } } diff --git a/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts b/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts index 79e73d5fd5..f6a33872a4 100644 --- a/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts +++ b/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts @@ -5,15 +5,20 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; +import recursiveAggregationFoldVerifierModule from "./recursiveAggregationFoldVerifier"; import thresholdDecryptedSharesAggregationVerifierModule from "./thresholdDecryptedSharesAggregationVerifier"; export default buildModule("BfvDecryptionVerifier", (m) => { const { thresholdDecryptedSharesAggregationVerifier } = m.useModule( thresholdDecryptedSharesAggregationVerifierModule, ); + const { recursiveAggregationFoldVerifier } = m.useModule( + recursiveAggregationFoldVerifierModule, + ); const bfvDecryptionVerifier = m.contract("BfvDecryptionVerifier", [ thresholdDecryptedSharesAggregationVerifier, + recursiveAggregationFoldVerifier, ]); return { bfvDecryptionVerifier }; diff --git a/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts b/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts index 726bb90431..b08e76dad1 100644 --- a/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts +++ b/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts @@ -5,15 +5,20 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; +import recursiveAggregationFoldVerifierModule from "./recursiveAggregationFoldVerifier"; import thresholdPkAggregationVerifierModule from "./thresholdPkAggregationVerifier"; export default buildModule("BfvPkVerifier", (m) => { const { thresholdPkAggregationVerifier } = m.useModule( thresholdPkAggregationVerifierModule, ); + const { recursiveAggregationFoldVerifier } = m.useModule( + recursiveAggregationFoldVerifierModule, + ); const bfvPkVerifier = m.contract("BfvPkVerifier", [ thresholdPkAggregationVerifier, + recursiveAggregationFoldVerifier, ]); return { bfvPkVerifier }; diff --git a/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts b/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts index a338dd9336..9faecfc7fc 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts @@ -31,6 +31,17 @@ export const deployAndSaveBfvDecryptionVerifier = async ( ); } + const foldVerifierArgs = readDeploymentArgs( + "RecursiveAggregationFoldVerifier", + chain, + ); + if (!foldVerifierArgs?.address) { + throw new Error( + "RecursiveAggregationFoldVerifier must be deployed first. " + + "Run deployAndSaveAllVerifiers or deploy verifiers.", + ); + } + const existing = readDeploymentArgs("BfvDecryptionVerifier", chain); if (existing?.address) { console.log( @@ -48,6 +59,7 @@ export const deployAndSaveBfvDecryptionVerifier = async ( ); const bfvDecryptionVerifier = await bfvDecryptionVerifierFactory.deploy( circuitVerifierArgs.address, + foldVerifierArgs.address, ); await bfvDecryptionVerifier.waitForDeployment(); diff --git a/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts b/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts index bef01b40bc..b2a3381075 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts @@ -31,6 +31,17 @@ export const deployAndSaveBfvPkVerifier = async ( ); } + const foldVerifierArgs = readDeploymentArgs( + "RecursiveAggregationFoldVerifier", + chain, + ); + if (!foldVerifierArgs?.address) { + throw new Error( + "RecursiveAggregationFoldVerifier must be deployed first. " + + "Run deployAndSaveAllVerifiers or deploy verifiers.", + ); + } + const existing = readDeploymentArgs("BfvPkVerifier", chain); if (existing?.address) { console.log(` BfvPkVerifier already deployed at ${existing.address}`); @@ -44,6 +55,7 @@ export const deployAndSaveBfvPkVerifier = async ( const bfvPkVerifierFactory = await ethers.getContractFactory("BfvPkVerifier"); const bfvPkVerifier = await bfvPkVerifierFactory.deploy( circuitVerifierArgs.address, + foldVerifierArgs.address, ); await bfvPkVerifier.waitForDeployment(); diff --git a/packages/enclave-contracts/tasks/enclave.ts b/packages/enclave-contracts/tasks/enclave.ts index 4a12ad0877..5274de08c6 100644 --- a/packages/enclave-contracts/tasks/enclave.ts +++ b/packages/enclave-contracts/tasks/enclave.ts @@ -264,8 +264,14 @@ export const publishCommittee = task( defaultValue: "", type: ArgumentType.STRING, }) + .addOption({ + name: "foldProof", + description: "fold proof to publish", + defaultValue: "0x", + type: ArgumentType.STRING, + }) .setAction(async () => ({ - default: async ({ e3Id, nodes, publicKey, proof }, hre) => { + default: async ({ e3Id, nodes, publicKey, proof, foldProof }, hre) => { const { deployAndSaveCiphernodeRegistryOwnable } = await import( "../scripts/deployAndSave/ciphernodeRegistryOwnable" ); @@ -299,6 +305,7 @@ export const publishCommittee = task( nodesToSend, publicKey, proof, + foldProof, ); console.log("Publishing committee... ", tx.hash); @@ -414,8 +421,23 @@ export const publishPlaintext = task( defaultValue: "", type: ArgumentType.STRING, }) + .addOption({ + name: "foldProof", + description: "fold proof to publish", + defaultValue: "0x", + type: ArgumentType.STRING, + }) + .addOption({ + name: "foldProofFile", + description: "file containing fold proof to publish", + defaultValue: "", + type: ArgumentType.STRING, + }) .setAction(async () => ({ - default: async ({ e3Id, data, dataFile, proof, proofFile }, hre) => { + default: async ( + { e3Id, data, dataFile, proof, proofFile, foldProof, foldProofFile }, + hre, + ) => { const { deployAndSaveEnclave } = await import( "../scripts/deployAndSave/enclave" ); @@ -432,16 +454,23 @@ export const publishPlaintext = task( } let proofToSend = proof; + let foldProofToSend = foldProof; if (proofFile) { const file = fs.readFileSync(proofFile); proofToSend = file.toString(); } + if (foldProofFile) { + const file = fs.readFileSync(foldProofFile); + foldProofToSend = file.toString(); + } + const tx = await enclave.publishPlaintextOutput( e3Id, dataToSend, proofToSend, + foldProofToSend, ); console.log("Publishing plaintext... ", tx.hash); diff --git a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts index ccd24c1584..887b43ad69 100644 --- a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts +++ b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts @@ -58,6 +58,8 @@ function encodeProof(rawProof: string, publicInputs: string[]): string { return abiCoder.encode(["bytes", "bytes32[]"], [rawProof, publicInputs]); } +const EMPTY_FOLD = "0x"; + describe("BfvDecryptionVerifier", function () { const deployWithMockCircuit = async () => { const [owner] = await ethers.getSigners(); @@ -65,10 +67,15 @@ describe("BfvDecryptionVerifier", function () { MockCircuitVerifierModule, ); const mockAddr = await mockCircuitVerifier.getAddress(); + const mockFold = await ( + await ethers.getContractFactory("MockCircuitVerifier") + ).deploy(); + await mockFold.waitForDeployment(); + const mockFoldAddr = await mockFold.getAddress(); const bfvDecryptionVerifier = await ( await ethers.getContractFactory("BfvDecryptionVerifier") - ).deploy(mockAddr); + ).deploy(mockAddr, mockFoldAddr); await bfvDecryptionVerifier.waitForDeployment(); const dv = BfvDecryptionVerifierFactory.connect( @@ -76,7 +83,8 @@ describe("BfvDecryptionVerifier", function () { owner, ); const mc = MockCircuitVerifierFactory.connect(mockAddr, owner); - return { bfvDecryptionVerifier: dv, mockCircuit: mc }; + const mf = MockCircuitVerifierFactory.connect(mockFoldAddr, owner); + return { bfvDecryptionVerifier: dv, mockCircuit: mc, mockFold: mf }; }; describe("reverts", function () { @@ -88,7 +96,11 @@ describe("BfvDecryptionVerifier", function () { const invalidProof = "0xdeadbeef"; // not abi.encode(bytes, bytes32[]) await expect( - bfvDecryptionVerifier.verify.staticCall(plaintextHash, invalidProof), + bfvDecryptionVerifier.verify.staticCall( + plaintextHash, + invalidProof, + EMPTY_FOLD, + ), ).to.be.revert(ethers); }); @@ -109,6 +121,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, proof, + EMPTY_FOLD, ); expect(result).to.equal(false); }); @@ -127,6 +140,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( wrongHash, proof, + EMPTY_FOLD, ); expect(result).to.equal(false); }); @@ -145,6 +159,29 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, proof, + EMPTY_FOLD, + ); + expect(result).to.equal(false); + }); + + it("returns false when fold proof is present but fold verifier returns false", async function () { + const { bfvDecryptionVerifier, mockCircuit, mockFold } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + await mockFold.setReturnValue(false); + + const messageCoeffs = [1n, 2n, 3n]; + const publicInputs = buildPublicInputsWithMessage(messageCoeffs); + const plaintextHash = plaintextToHash(messageCoeffs); + const foldPi = ["0x" + "01".repeat(32)]; + const foldProof = encodeProof("0x02", foldPi); + const proof = encodeProof("0x01", publicInputs); + + const result = await bfvDecryptionVerifier.verify.staticCall( + plaintextHash, + proof, + foldProof, ); expect(result).to.equal(false); }); @@ -165,6 +202,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, proof, + EMPTY_FOLD, ); expect(result).to.equal(true); }); @@ -186,6 +224,29 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, proof, + EMPTY_FOLD, + ); + expect(result).to.equal(true); + }); + + it("returns true when fold proof is present and fold verifies", async function () { + const { bfvDecryptionVerifier, mockCircuit, mockFold } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + await mockFold.setReturnValue(true); + + const messageCoeffs = [1n, 2n, 3n]; + const publicInputs = buildPublicInputsWithMessage(messageCoeffs); + const plaintextHash = plaintextToHash(messageCoeffs); + const foldPi = ["0x" + "01".repeat(32)]; + const foldProof = encodeProof("0xaa", foldPi); + const proof = encodeProof("0x01", publicInputs); + + const result = await bfvDecryptionVerifier.verify.staticCall( + plaintextHash, + proof, + foldProof, ); expect(result).to.equal(true); }); diff --git a/packages/enclave-contracts/test/BfvPkVerifier.spec.ts b/packages/enclave-contracts/test/BfvPkVerifier.spec.ts index 54a609fa03..64c64a0e66 100644 --- a/packages/enclave-contracts/test/BfvPkVerifier.spec.ts +++ b/packages/enclave-contracts/test/BfvPkVerifier.spec.ts @@ -20,6 +20,8 @@ function encodeProof(rawProof: string, publicInputs: string[]): string { return abiCoder.encode(["bytes", "bytes32[]"], [rawProof, publicInputs]); } +const EMPTY_FOLD = "0x"; + describe("BfvPkVerifier", function () { const deployWithMockCircuit = async () => { const [owner] = await ethers.getSigners(); @@ -27,10 +29,15 @@ describe("BfvPkVerifier", function () { MockCircuitVerifierModule, ); const mockAddr = await mockCircuitVerifier.getAddress(); + const mockFold = await ( + await ethers.getContractFactory("MockCircuitVerifier") + ).deploy(); + await mockFold.waitForDeployment(); + const mockFoldAddr = await mockFold.getAddress(); const bfvPkVerifier = await ( await ethers.getContractFactory("BfvPkVerifier") - ).deploy(mockAddr); + ).deploy(mockAddr, mockFoldAddr); await bfvPkVerifier.waitForDeployment(); const pk = BfvPkVerifierFactory.connect( @@ -38,7 +45,8 @@ describe("BfvPkVerifier", function () { owner, ); const mc = MockCircuitVerifierFactory.connect(mockAddr, owner); - return { bfvPkVerifier: pk, mockCircuit: mc }; + const mf = MockCircuitVerifierFactory.connect(mockFoldAddr, owner); + return { bfvPkVerifier: pk, mockCircuit: mc, mockFold: mf }; }; describe("reverts", function () { @@ -46,16 +54,18 @@ describe("BfvPkVerifier", function () { const { bfvPkVerifier } = await loadFixture(deployWithMockCircuit); const invalidProof = "0xdeadbeef"; - await expect(bfvPkVerifier.verify.staticCall(invalidProof)).to.be.revert( - ethers, - ); + await expect( + bfvPkVerifier.verify.staticCall(invalidProof, EMPTY_FOLD), + ).to.be.revert(ethers); }); it("reverts when publicInputs is empty", async function () { const { bfvPkVerifier } = await loadFixture(deployWithMockCircuit); const proof = encodeProof("0x01", []); - await expect(bfvPkVerifier.verify.staticCall(proof)).to.be.revert(ethers); + await expect( + bfvPkVerifier.verify.staticCall(proof, EMPTY_FOLD), + ).to.be.revert(ethers); }); it("reverts when circuit verifier returns false", async function () { @@ -67,7 +77,26 @@ describe("BfvPkVerifier", function () { const commitment = ethers.keccak256("0x1234"); const proof = encodeProof("0x01", [commitment]); - await expect(bfvPkVerifier.verify.staticCall(proof)).to.be.revert(ethers); + await expect( + bfvPkVerifier.verify.staticCall(proof, EMPTY_FOLD), + ).to.be.revert(ethers); + }); + + it("reverts when fold verifier returns false and fold proof is present", async function () { + const { bfvPkVerifier, mockCircuit, mockFold } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + await mockFold.setReturnValue(false); + + const commitment = ethers.keccak256("0x1234"); + const proof = encodeProof("0x01", [commitment]); + const foldPi = ["0x" + "01".repeat(32)]; + const foldProof = encodeProof("0x02", foldPi); + + await expect( + bfvPkVerifier.verify.staticCall(proof, foldProof), + ).to.be.revert(ethers); }); }); @@ -85,7 +114,7 @@ describe("BfvPkVerifier", function () { commitment, ]); - const result = await bfvPkVerifier.verify.staticCall(proof); + const result = await bfvPkVerifier.verify.staticCall(proof, EMPTY_FOLD); expect(result).to.equal(commitment); }); @@ -98,7 +127,27 @@ describe("BfvPkVerifier", function () { const commitment = ethers.id("committee-pk"); const proof = encodeProof("0x", [commitment]); - const result = await bfvPkVerifier.verify.staticCall(proof); + const result = await bfvPkVerifier.verify.staticCall(proof, EMPTY_FOLD); + expect(result).to.equal(commitment); + }); + + it("returns commitment when fold proof is present and fold verifies", async function () { + const { bfvPkVerifier, mockCircuit, mockFold } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + await mockFold.setReturnValue(true); + + const commitment = ethers.keccak256("0xabcd"); + const proof = encodeProof("0x0102", [ + "0x" + "00".repeat(32), + "0x" + "00".repeat(32), + commitment, + ]); + const foldPi = ["0x" + "02".repeat(32)]; + const foldProof = encodeProof("0x99", foldPi); + + const result = await bfvPkVerifier.verify.staticCall(proof, foldProof); expect(result).to.equal(commitment); }); }); diff --git a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts index 566251b735..26d37e8b9d 100644 --- a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -446,7 +446,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); // Verify stage transitioned to KeyPublished (after publishCommittee which calls onKeyPublished) stage = await enclave.getE3Stage(0); @@ -491,7 +491,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await expect(registry.publishCommittee(0, nodes, publicKey, pkProof)) + await expect(registry.publishCommittee(0, nodes, publicKey, pkProof, "0x")) .to.emit(enclave, "CommitteeFormed") .withArgs(0); }); @@ -753,7 +753,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); // 2. Wait past compute deadline → mark as failed const e3 = await enclave.getE3(0); @@ -857,7 +857,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); // 2. Fail via compute timeout const e3 = await enclave.getE3(0); @@ -1109,7 +1109,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); stage = await enclave.getE3Stage(0); expect(stage).to.equal(3); // KeyPublished @@ -1188,7 +1188,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); stage = await enclave.getE3Stage(0); expect(stage).to.equal(3); // KeyPublished @@ -1431,7 +1431,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); expect(await enclave.getE3Stage(0)).to.equal(3); // KeyPublished @@ -1484,7 +1484,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ); const plaintextOutput = "0x" + "cd".repeat(100); - await enclave.publishPlaintextOutput(0, plaintextOutput, proofBytes); + await enclave.publishPlaintextOutput(0, plaintextOutput, proofBytes, "0x"); expect(await enclave.getE3Stage(0)).to.equal(5); // Complete // 4. Verify escrowed slashed funds were distributed @@ -1562,7 +1562,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); expect(await enclave.getE3Stage(0)).to.equal(3); // KeyPublished @@ -1577,7 +1577,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { // 4. Publish plaintext output const plaintextOutput = "0x" + "cd".repeat(100); - await enclave.publishPlaintextOutput(0, plaintextOutput, proof); + await enclave.publishPlaintextOutput(0, plaintextOutput, proof, "0x"); expect(await enclave.getE3Stage(0)).to.equal(5); // Complete // Cannot mark completed E3 as failed @@ -1621,7 +1621,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkProof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(0, nodes, publicKey, pkProof); + await registry.publishCommittee(0, nodes, publicKey, pkProof, "0x"); // Publish outputs const e3 = await enclave.getE3(0); @@ -1632,7 +1632,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await enclave.publishCiphertextOutput(0, ciphertextOutput, proof); const plaintextOutput = "0x" + "cd".repeat(100); - await enclave.publishPlaintextOutput(0, plaintextOutput, proof); + await enclave.publishPlaintextOutput(0, plaintextOutput, proof, "0x"); // Verify E3 is complete expect(await enclave.getE3Stage(0)).to.equal(5); // Complete diff --git a/packages/enclave-contracts/test/Enclave.spec.ts b/packages/enclave-contracts/test/Enclave.spec.ts index 5c2999a5e2..82096a00c1 100644 --- a/packages/enclave-contracts/test/Enclave.spec.ts +++ b/packages/enclave-contracts/test/Enclave.spec.ts @@ -82,7 +82,7 @@ describe("Enclave", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(e3Id); const proof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(e3Id, nodes, publicKey, proof); + await registry.publishCommittee(e3Id, nodes, publicKey, proof, "0x"); }; // Helper function to approve USDC and make request @@ -1022,7 +1022,7 @@ describe("Enclave", function () { const { enclave } = await loadFixture(setup); const e3Id = 0; - await expect(enclave.publishPlaintextOutput(e3Id, data, "0x")) + await expect(enclave.publishPlaintextOutput(e3Id, data, "0x", "0x")) .to.be.revertedWithCustomError(enclave, "E3DoesNotExist") .withArgs(e3Id); }); @@ -1056,7 +1056,7 @@ describe("Enclave", function () { [operator1, operator2, operator3], ); await expect( - enclave.publishPlaintextOutput(e3Id, data, "0x"), + enclave.publishPlaintextOutput(e3Id, data, "0x", "0x"), ).to.be.revertedWithCustomError(enclave, "InvalidStage"); }); it("reverts if plaintextOutput has already been published", async function () { @@ -1089,9 +1089,9 @@ describe("Enclave", function () { ); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); - await enclave.publishPlaintextOutput(e3Id, data, proof); + await enclave.publishPlaintextOutput(e3Id, data, proof, "0x"); await expect( - enclave.publishPlaintextOutput(e3Id, data, proof), + enclave.publishPlaintextOutput(e3Id, data, proof, "0x"), ).to.be.revertedWithCustomError(enclave, "InvalidStage"); }); it("reverts if output is not valid", async function () { @@ -1124,7 +1124,7 @@ describe("Enclave", function () { ); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); - await expect(enclave.publishPlaintextOutput(e3Id, data, "0x")) + await expect(enclave.publishPlaintextOutput(e3Id, data, "0x", "0x")) .to.be.revertedWithCustomError(enclave, "InvalidOutput") .withArgs(data); }); @@ -1158,7 +1158,7 @@ describe("Enclave", function () { ); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); - expect(await enclave.publishPlaintextOutput(e3Id, data, proof)); + expect(await enclave.publishPlaintextOutput(e3Id, data, proof, "0x")); const e3 = await enclave.getE3(e3Id); expect(e3.plaintextOutput).to.equal(data); @@ -1194,7 +1194,12 @@ describe("Enclave", function () { await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); expect( - await enclave.publishPlaintextOutput.staticCall(e3Id, data, proof), + await enclave.publishPlaintextOutput.staticCall( + e3Id, + data, + proof, + "0x", + ), ).to.equal(true); }); it("emits PlaintextOutputPublished event", async function () { @@ -1227,7 +1232,9 @@ describe("Enclave", function () { ); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); - await expect(await enclave.publishPlaintextOutput(e3Id, data, proof)) + await expect( + await enclave.publishPlaintextOutput(e3Id, data, proof, "0x"), + ) .to.emit(enclave, "PlaintextOutputPublished") .withArgs(e3Id, data); }); diff --git a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts index eec7d661cc..11d7004f26 100644 --- a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts +++ b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts @@ -444,6 +444,7 @@ describe("CiphernodeRegistryOwnable", function () { ], data, c5Proof, + "0x", ), ).to.be.revertedWithCustomError(registry, "OwnableUnauthorizedAccount"); }); @@ -479,6 +480,7 @@ describe("CiphernodeRegistryOwnable", function () { ], data, c5Proof, + "0x", ); expect(await registry.committeePublicKey(0)).to.equal(dataHash); }); @@ -516,6 +518,7 @@ describe("CiphernodeRegistryOwnable", function () { ], data, c5Proof, + "0x", ), ) .to.emit(registry, "CommitteePublished") @@ -657,6 +660,7 @@ describe("CiphernodeRegistryOwnable", function () { ], data, c5Proof, + "0x", ); expect(await registry.committeePublicKey(e3Id)).to.equal(dataHash); }); diff --git a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts index b580c20b79..fe26883230 100644 --- a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts +++ b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts @@ -345,7 +345,7 @@ describe("Committee Expulsion & Fault Tolerance", function () { const nodes = await Promise.all(operators.map((op) => op.getAddress())); const publicKey = ethers.toUtf8Bytes("fake-public-key"); const proof = encodePkProof(ethers.keccak256(publicKey)); - await registry.publishCommittee(e3Id, nodes, publicKey, proof); + await registry.publishCommittee(e3Id, nodes, publicKey, proof, "0x"); } // ── Return ─────────────────────────────────────────────────────────────────