diff --git a/-b b/-b deleted file mode 100644 index f9f1056..0000000 --- a/-b +++ /dev/null @@ -1,5 +0,0 @@ -# Netscape HTTP Cookie File -# https://curl.se/docs/http-cookies.html -# This file was generated by libcurl! Edit at your own risk. - -#HttpOnly_localhost FALSE / FALSE 1757248505 sessionId s%3ARIwffwSv4wqUqAqxpOk_ya9pUWlGlu4W.yc4Bi0rNrhM9%2BUzO0IUZezYTJJfB2ybrng1a3P0imjw diff --git a/backend/artifacts/contracts/DLE.sol/DLE.dbg.json b/backend/artifacts/contracts/DLE.sol/DLE.dbg.json index 8649709..9b902d5 100644 --- a/backend/artifacts/contracts/DLE.sol/DLE.dbg.json +++ b/backend/artifacts/contracts/DLE.sol/DLE.dbg.json @@ -1,4 +1,4 @@ { "_format": "hh-sol-dbg-1", - "buildInfo": "../../build-info/362ff3981c938c72363f6427a454b84b.json" + "buildInfo": "../../build-info/998bc5520c3173891dd242df2365077b.json" } diff --git a/backend/artifacts/contracts/DLE.sol/DLE.json b/backend/artifacts/contracts/DLE.sol/DLE.json index 7e15e73..19b9866 100644 --- a/backend/artifacts/contracts/DLE.sol/DLE.json +++ b/backend/artifacts/contracts/DLE.sol/DLE.json @@ -81,6 +81,54 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "CheckpointUnorderedInsertion", + "type": "error" + }, + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "increasedSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "cap", + "type": "uint256" + } + ], + "name": "ERC20ExceededSafeSupply", + "type": "error" + }, { "inputs": [ { @@ -167,11 +215,118 @@ "name": "ERC20InvalidSpender", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ERC2612ExpiredSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC2612InvalidSigner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + }, + { + "internalType": "uint48", + "name": "clock", + "type": "uint48" + } + ], + "name": "ERC5805FutureLookup", + "type": "error" + }, + { + "inputs": [], + "name": "ERC6372InconsistentClock", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentNonce", + "type": "uint256" + } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidShortString", + "type": "error" + }, { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "str", + "type": "string" + } + ], + "name": "StringTooLong", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + } + ], + "name": "VotesExpiredSignature", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -210,25 +365,6 @@ "name": "ChainAdded", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - } - ], - "name": "ChainMerkleRootSet", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -242,56 +378,6 @@ "name": "ChainRemoved", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "proposalId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fromChainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "toChainId", - "type": "uint256" - } - ], - "name": "CrossChainExecutionSync", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "proposalId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fromChainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "toChainId", - "type": "uint256" - } - ], - "name": "CrossChainVoteSync", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -456,75 +542,56 @@ "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint256", - "name": "proposalId", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" }, { "indexed": true, "internalType": "address", - "name": "initiator", + "name": "fromDelegate", "type": "address" }, { - "indexed": false, - "internalType": "string", - "name": "description", - "type": "string" + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" } ], - "name": "DeactivationProposalCreated", + "name": "DelegateChanged", "type": "event" }, { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, { "indexed": false, "internalType": "uint256", - "name": "proposalId", + "name": "previousVotes", "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "executedBy", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "newVotes", + "type": "uint256" } ], - "name": "DeactivationProposalExecuted", + "name": "DelegateVotesChanged", "type": "event" }, { "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "proposalId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "voter", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "support", - "type": "bool" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "votingPower", - "type": "uint256" - } - ], - "name": "DeactivationProposalVoted", + "inputs": [], + "name": "EIP712DomainChanged", "type": "event" }, { @@ -578,6 +645,25 @@ "name": "ModuleRemoved", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "ProposalCancelled", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -622,6 +708,82 @@ "name": "ProposalExecuted", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "ProposalExecutionApprovedInChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "governanceChainId", + "type": "uint256" + } + ], + "name": "ProposalGovernanceChainSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "targetChains", + "type": "uint256[]" + } + ], + "name": "ProposalTargetsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timelock", + "type": "uint256" + } + ], + "name": "ProposalTimelockSet", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -710,6 +872,32 @@ "name": "Transfer", "type": "event" }, + { + "inputs": [], + "name": "CLOCK_MODE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -733,13 +921,19 @@ "inputs": [ { "internalType": "uint256", - "name": "_chainId", + "name": "", "type": "uint256" } ], - "name": "addSupportedChain", - "outputs": [], - "stateMutability": "nonpayable", + "name": "allProposalIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", "type": "function" }, { @@ -813,19 +1007,18 @@ "inputs": [ { "internalType": "uint256", - "name": "", + "name": "_proposalId", "type": "uint256" - } - ], - "name": "chainMerkleRoots", - "outputs": [ + }, { - "internalType": "bytes32", - "name": "", - "type": "bytes32" + "internalType": "string", + "name": "reason", + "type": "string" } ], - "stateMutability": "view", + "name": "cancelProposal", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -847,30 +1040,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proposalId", - "type": "uint256" - } - ], - "name": "checkDeactivationProposalResult", - "outputs": [ - { - "internalType": "bool", - "name": "passed", - "type": "bool" - }, - { - "internalType": "bool", - "name": "quorumReached", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -914,6 +1083,55 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint48", + "name": "_key", + "type": "uint48" + }, + { + "internalType": "uint208", + "name": "_value", + "type": "uint208" + } + ], + "internalType": "struct Checkpoints.Checkpoint208", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clock", + "outputs": [ + { + "internalType": "uint48", + "name": "", + "type": "uint48" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -953,35 +1171,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "string", - "name": "_description", - "type": "string" - }, - { - "internalType": "uint256", - "name": "_duration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_chainId", - "type": "uint256" - } - ], - "name": "createDeactivationProposal", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -1003,6 +1192,16 @@ "internalType": "uint256", "name": "_governanceChainId", "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_targetChains", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_timelockDelay", + "type": "uint256" } ], "name": "createProposal", @@ -1065,19 +1264,12 @@ }, { "inputs": [], - "name": "deactivate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "deactivationProposalCounter", + "name": "decimals", "outputs": [ { - "internalType": "uint256", + "internalType": "uint8", "name": "", - "type": "uint256" + "type": "uint8" } ], "stateMutability": "view", @@ -1086,65 +1278,68 @@ { "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "address", + "name": "delegatee", + "type": "address" } ], - "name": "deactivationProposals", - "outputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "string", - "name": "description", - "type": "string" - }, - { - "internalType": "uint256", - "name": "forVotes", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "againstVotes", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "executed", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "initiator", + "name": "delegatee", "type": "address" }, { "internalType": "uint256", - "name": "chainId", + "name": "nonce", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" } ], - "stateMutability": "view", + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "decimals", + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", "outputs": [ { - "internalType": "uint8", + "internalType": "address", "name": "", - "type": "uint8" + "type": "address" } ], "stateMutability": "view", @@ -1204,16 +1399,46 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, { "internalType": "uint256", - "name": "_proposalId", + "name": "chainId", "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" } ], - "name": "executeDeactivationProposal", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { @@ -1233,38 +1458,23 @@ "inputs": [ { "internalType": "uint256", - "name": "", + "name": "_proposalId", "type": "uint256" - } - ], - "name": "executedProposals", - "outputs": [ + }, { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + "internalType": "address[]", + "name": "signers", + "type": "address[]" + }, { - "internalType": "uint256", - "name": "_chainId", - "type": "uint256" + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" } ], - "name": "getChainMerkleRoot", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", + "name": "executeProposalBySignatures", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -1345,6 +1555,91 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getGovernanceParams", + "outputs": [ + { + "internalType": "uint256", + "name": "quorumPct", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supportedCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_moduleId", + "type": "bytes32" + } + ], + "name": "getModuleAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1353,7 +1648,26 @@ "type": "uint256" } ], - "name": "getDeactivationProposal", + "name": "getProposalState", + "outputs": [ + { + "internalType": "uint8", + "name": "state", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_proposalId", + "type": "uint256" + } + ], + "name": "getProposalSummary", "outputs": [ { "internalType": "uint256", @@ -1380,6 +1694,11 @@ "name": "executed", "type": "bool" }, + { + "internalType": "bool", + "name": "canceled", + "type": "bool" + }, { "internalType": "uint256", "name": "deadline", @@ -1392,7 +1711,69 @@ }, { "internalType": "uint256", - "name": "chainId", + "name": "governanceChainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timelock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "snapshotTimepoint", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "targets", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_proposalId", + "type": "uint256" + } + ], + "name": "getProposalVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "forVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "againstVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "quorumRequired", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProposalsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", "type": "uint256" } ], @@ -1402,17 +1783,17 @@ { "inputs": [ { - "internalType": "bytes32", - "name": "_moduleId", - "type": "bytes32" + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" } ], - "name": "getModuleAddress", + "name": "getQuorumAt", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -1450,6 +1831,49 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getVotingPowerAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "isActive", @@ -1514,6 +1938,43 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "listProposals", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "listSupportedChains", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1548,26 +2009,83 @@ }, { "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" - } - ], - "name": "processedProofs", - "outputs": [ + }, { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" } ], - "stateMutability": "view", + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -1618,6 +2136,11 @@ "name": "executed", "type": "bool" }, + { + "internalType": "bool", + "name": "canceled", + "type": "bool" + }, { "internalType": "uint256", "name": "deadline", @@ -1632,6 +2155,21 @@ "internalType": "bytes", "name": "operation", "type": "bytes" + }, + { + "internalType": "uint256", + "name": "governanceChainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timelock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "snapshotTimepoint", + "type": "uint256" } ], "stateMutability": "view", @@ -1650,37 +2188,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_chainId", - "type": "uint256" - } - ], - "name": "removeSupportedChain", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_chainId", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_merkleRoot", - "type": "bytes32" - } - ], - "name": "setChainMerkleRoot", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -1732,29 +2239,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proposalId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_fromChainId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_proof", - "type": "bytes" - } - ], - "name": "syncExecutionFromChain", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -1768,39 +2252,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proposalId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_fromChainId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_forVotes", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_againstVotes", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_proof", - "type": "bytes" - } - ], - "name": "syncVoteFromChain", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "totalSupply", @@ -1884,28 +2335,10 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proposalId", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "_support", - "type": "bool" - } - ], - "name": "voteDeactivation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" } ], - "bytecode": "0x608060405234620011625762005e4e80380390816200001e81620011c3565b918239604081838101031262001162578051906001600160401b03821162001162576101809283838301828401031262001162576040519384016001600160401b03811185821017620006bb57604052818301516001600160401b0381116200116257620000949082840190858501016200120e565b8452818301602001516001600160401b0381116200116257620000bf9082840190858501016200120e565b6020850152818301604001516001600160401b0381116200116257620000ed9082840190858501016200120e565b6040850152818301606001516001600160401b03811162001162576200011b9082840190858501016200120e565b60608501528183016080818101519086015260a0808201519086015260c001516001600160401b038111620011625783830101818301601f8201121562001162578051620001736200016d8262001265565b620011c3565b9160208084848152019260051b820101918486018311620011625760208201905b8382106200118f575050505060c085015281830160e08181015190860152610100808201519086015261012001516001600160401b0381116200116257818301601f8286860101011215620011625780848401015190620001f96200016d8362001265565b91602083828152019184860160208360051b838a8a01010101116200116257916020838888010101925b60208360051b828a8a01010101841062001167575050505061012085015281830161014001516001600160401b03811162001162576200026b9082840190858501016200127d565b6101408501528183016101600151926001600160401b03841162001162576020936200029d928401918401016200127d565b610160840152015181516020830151815191939092916001600160401b038111620006bb57620002cf600354620012da565b601f81116200110f575b506020601f82116001146200109f57819293949560009262001093575b50508160011b916000199060031b1c1916176003555b82516001600160401b038111620006bb576200032a600454620012da565b601f811162001040575b506020601f821160011462000fd1578192939460009262000fc5575b50508160011b916000199060031b1c1916176004555b6001600555805191602082015160408301516060840151608085015160a08601519060c08701519260e088015194604051968761014081011060018060401b036101408a011117620006bb5761014088016040528a8852602088015260408701526060860152608085015260a084015260c083015260e0820152426101008201526001610120820152835160018060401b038111620006bb576200040c600654620012da565b601f811162000f72575b506020601f821160011462000f0257819293949560009262000ef6575b50508160011b916000199060031b1c1916176006555b602081015180519093906001600160401b038111620006bb576200046f600754620012da565b601f811162000ea3575b506020601f821160011462000e3357819293949560009262000e27575b50508160011b916000199060031b1c1916176007555b604082015180519093906001600160401b038111620006bb57620004d2600854620012da565b601f811162000dd4575b506020601f821160011462000d6457819293949560009262000d58575b50508160011b916000199060031b1c1916176008555b606083015180519093906001600160401b038111620006bb5762000535600954620012da565b601f811162000d05575b506020601f821160011462000c9557819293949560009262000c89575b50508160011b916000199060031b1c1916176009555b6080810151600a5560a0810151600b5560c0810151805190680100000000000000008211620006bb57600c5482600c5580831062000bec575b50600c60009081527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c792916020015b82821062000aba5786866101208760e0810151600d55610100810151600e550151151560ff8019600f5416911617600f5561010082015160105560125560005b6101608201518051821015620006d15781620006369162001340565b5160005260166020526040600020600160ff19825416179055620006608161016084015162001340565b51906017549168010000000000000000831015620006bb576001830180601755831015620006a5576200069f9260176000526020600020015562001330565b6200061a565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8261012081015151610140820151510362000a7557610120810151511562000a305760005b610120820151805182101562000862576001600160a01b039081906200071e90849062001340565b5116156200082e57620007378261014085015162001340565b5115620007fb576200074f8261012085015162001340565b511690620007638161014085015162001340565b51918015620007e2576002548381018111620007cc577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602085620007c6966000940160025584845283825260408420818154019055604051908152a362001330565b620006f6565b634e487b7160e01b600052601160045260246000fd5b60405163ec442f0560e01b815260006004820152602490fd5b60405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b8261012081015161014082015190604051916040830160408452825180915260206060850193019060005b81811062000a1057867ff9e7aa11bcdcbb8ac33b5dba92fca799ef091e54c29270822065501d8edea1a58780620008cd8989838203602085015262001355565b0390a18051602082015160408301519260608101516080820151906200095260a0840151916200094360c0860151986200093461016060e089015198015198620009256040519b6101408d526101408d01906200138b565b908b820360208d01526200138b565b9089820360408b01526200138b565b9087820360608901526200138b565b91608086015260a085015283810360c0850152845180825260208201916020808360051b8301019701926000915b838310620009e0577f11b248463a1620b36a975da8f250009f56fb5dd0e9d5027a90a834d0ee84d6f68880620009cd8c8b8b60e08501523061010085015283820361012085015262001355565b0390a1604051614a9b9081620013b38239f35b909192939760208062000a00600193601f198682030187528c516200138b565b9a01930193019193929062000980565b82516001600160a01b03168552602094850194909201916001016200088d565b60405162461bcd60e51b815260206004820152601360248201527f4e6f20696e697469616c20706172746e657273000000000000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527f417272617973206c656e677468206d69736d61746368000000000000000000006044820152606490fd5b80518051906001600160401b038211620006bb5762000ada8654620012da565b601f811162000baa575b50602090601f831160011462000b3557928260019493602093869560009262000b29575b5050600019600383901b1c191690841b1787555b01940191019092620005da565b01519050388062000b08565b908660005260206000209160005b601f198516811062000b91575083602093600196938796938794601f1981161062000b77575b505050811b01875562000b1c565b015160001960f88460031b161c1916905538808062000b69565b9192602060018192868501518155019401920162000b43565b62000bda90876000526020600020601f850160051c8101916020861062000be1575b601f0160051c019062001317565b3862000ae4565b909150819062000bcc565b600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7908382015b818301811062000c29575050620005ab565b8062000c3860019254620012da565b8062000c47575b500162000c17565b601f8111831462000c5f5750600081555b3862000c3f565b60009082825262000c7f601f60208420920160051c820185830162001317565b8183555562000c58565b0151905038806200055c565b600960005260206000209060005b601f198416811062000cec575060019394959683601f1981161062000cd2575b505050811b0160095562000572565b015160001960f88460031b161c1916905538808062000cc3565b9091602060018192858b01518155019301910162000ca3565b600960005262000d51907f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af601f840160051c8101916020851062000be157601f0160051c019062001317565b386200053f565b015190503880620004f9565b600860005260206000209060005b601f198416811062000dbb575060019394959683601f1981161062000da1575b505050811b016008556200050f565b015160001960f88460031b161c1916905538808062000d92565b9091602060018192858b01518155019301910162000d72565b600860005262000e20907ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3601f840160051c8101916020851062000be157601f0160051c019062001317565b38620004dc565b01519050388062000496565b600760005260206000209060005b601f198416811062000e8a575060019394959683601f1981161062000e70575b505050811b01600755620004ac565b015160001960f88460031b161c1916905538808062000e61565b9091602060018192858b01518155019301910162000e41565b600760005262000eef907fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688601f840160051c8101916020851062000be157601f0160051c019062001317565b3862000479565b01519050388062000433565b600660005260206000209060005b601f198416811062000f59575060019394959683601f1981161062000f3f575b505050811b0160065562000449565b015160001960f88460031b161c1916905538808062000f30565b9091602060018192858b01518155019301910162000f10565b600660005262000fbe907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f601f840160051c8101916020851062000be157601f0160051c019062001317565b3862000416565b01519050388062000350565b600460005260206000209060005b601f1984168110620010275750600193949583601f198116106200100d575b505050811b0160045562000366565b015160001960f88460031b161c1916905538808062000ffe565b9091602060018192858a01518155019301910162000fdf565b60046000526200108c907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f840160051c8101916020851062000be157601f0160051c019062001317565b3862000334565b015190503880620002f6565b600360005260206000209060005b601f1984168110620010f6575060019394959683601f19811610620010dc575b505050811b016003556200030c565b015160001960f88460031b161c19169055388080620010cd565b9091602060018192858b015181550193019101620010ad565b60036000526200115b907fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851062000be157601f0160051c019062001317565b38620002d9565b600080fd5b8351916001600160a01b03831683036200116257602081819482935201940193915062000223565b81516001600160401b0381116200116257602091620011b78392838a8c01918801016200120e565b81520191019062000194565b6040519190601f01601f191682016001600160401b03811183821017620006bb57604052565b60005b838110620011fd5750506000910152565b8181015183820152602001620011ec565b81601f82011215620011625780516001600160401b038111620006bb5762001240601f8201601f1916602001620011c3565b92818452602082840101116200116257620012629160208085019101620011e9565b90565b6001600160401b038111620006bb5760051b60200190565b9080601f8301121562001162578151906200129c6200016d8362001265565b9182938184526020808095019260051b82010192831162001162578301905b828210620012ca575050505090565b81518152908301908301620012bb565b90600182811c921680156200130c575b6020831014620012f657565b634e487b7160e01b600052602260045260246000fd5b91607f1691620012ea565b81811062001323575050565b6000815560010162001317565b6000198114620007cc5760010190565b8051821015620006a55760209160051b010190565b90815180825260208080930193019160005b82811062001376575050505090565b83518552938101939281019260010162001367565b90602091620013a681518092818552858086019101620011e9565b601f01601f191601019056fe60808060405260048036101561001457600080fd5b60003560e01c918263013cf08b14612bdc57508163044bc2bd1461297557816306fdde03146128a75781630933fad414612759578163095ea7b3146126ba5781630c0512e91461269c5781630c4844aa1461249c5781630d61b5191461229c5781631552d75c1461219b57816318160ddd1461217d578163204c5d1f14611f0e57816322dbefbb14610da057816322f3e2d414611ed75781632388b53114611eb957816323b872dd14611dc15781632441d76f14611d845781632519ae5c14611acb578163313ce56714611aaf5781633b60288a14611a80578163456d10c1146117ba5781634b14579314610ad45781634cf2ab32146117855781634de184f6146117685781634fa76ec91461174a57816351b42b001461159c5781635221c1f01461156d578163548d496f1461156d578163553b527a146114f3578163560cada51461141d5781635cf0e8a4146113785781635d57d260146113965781636cbadbfa146113785781636dcf811d1461135557816370a082311461131b5781637481c8e91461039c5781637ce288ea146110bb5781637e5a9b47146110a057816387188a0014610f0f57816395d89b4114610e285781639a49bdde14610e03578163a9059cbb14610dd2578163b0b6cc1a14610da0578163b359451014610b03578163b3fe8bcb14610ad4578163b5b353be14610868578163bc62f34e14610835578163c9a3c0c714610532578163c9d27afe14610417578163dd62ed3e146103c6578163e1605aa21461039c578163e49a62e91461037557508063eced3dfb146103575763f2c26a471461026857600080fd5b34610352576000366003190112610352576103076040516102938161028c81612cd6565b0382612fd7565b6040516102a38161028c81612d7a565b604051906102bb826102b481612e01565b0383612fd7565b604051916102d3836102cc81612e88565b0384612fd7565b600a5492600b54610331600d5492610323600e549561031560ff600f5416986040519c8d9c8d61012090818152019061301b565b8c810360208e01529061301b565b908a820360408c015261301b565b9088820360608a015261301b565b94608087015260a086015260c085015260e084015215156101008301520390f35b600080fd5b34610352576000366003190112610352576020601754604051908152f35b346103525760203660031901126103525761039260209135613861565b6040519015158152f35b34610352576020366003190112610352573560005260196020526020604060002054604051908152f35b34610352576040366003190112610352576103df6130a2565b6103e76130b8565b9060018060a01b038091166000526001602052604060002091166000526020526020604060002054604051908152f35b346103525760807f78975aaf742630489badd22949b88ac50eaaea576339ee05440b671a33bfb6a991610449366130ce565b610454929192613597565b8260005260206015815261048e60ff60406000209461047587875414613448565b61048460058701544210613494565b85015416156134cf565b6008830192336000528382526104ac60ff604060002054161561351b565b33600052600082526104c46040600020541515613557565b33600052600082526040600020549382526040600020600160ff198254161790558260001461051d576002016104fb848254613265565b90555b6040519384523390840152151560408301526060820152a16001600555005b60030161052b848254613265565b90556104fe565b34610352576080366003190112610352576001600160401b0390803582811161035257610562903690830161305b565b6044359160643593846000526105966105916020966016885261058c60ff6040600020541661332c565b613831565b61336e565b83600052601485526105af60ff60406000205416614922565b33600052600085526105c76040600020541515613288565b601154936105d4856133b0565b601155846000526015865260406000209085825560019182810186518581116108205761060b816106058454612c9c565b846133d6565b808a601f82116001146107be576000916107b3575b50600019600383901b1c191690851b1790555b61063f60243542613265565b60058201556006810180546001600160a01b03191633179055604051633972e9fb60e21b89820152602480820193909352918252606082018481118382101761079e57906007916040520193815193841161078957506106a9836106a38654612c9c565b866133d6565b8690601f841160011461070e5792806106f895938193600080516020614a468339815191529896600094610703575b50501b916000199060031b1c19161790555b60405191829133868461341d565b0390a1604051908152f35b015192508a806106d8565b90601f9392931983169185600052886000209260005b8a82821061077557505091600080516020614a4683398151915297959391856106f89896941061075c575b505050811b0190556106ea565b015160001960f88460031b161c1916905588808061074f565b838501518655948701949384019301610724565b604190634e487b7160e01b6000525260246000fd5b604186634e487b7160e01b6000525260246000fd5b90508801518b610620565b60008481528c81208894509190601f198416908e5b8d83831061080a5750505083116107f1575b5050811b019055610633565b8a015160001960f88460031b161c191690558b806107e5565b84015185558a969094019392830192018e6107d3565b604187634e487b7160e01b6000525260246000fd5b34610352576020366003190112610352576108509035614a0a565b604080519215158352901515602083015290f35b0390f35b34610352576060366003190112610352576001600160401b0390803582811161035257610898903690830161305b565b60243592604435906108af60ff601d541615614966565b336000526020946000865260406000205415610a77576108d08115156132e0565b82600052601686526108e960ff6040600020541661332c565b601c54946108f6866133b0565b601c5585600052601b8752604060002092868455600190818501918751918211610a625761092e826109288554612c9c565b856133d6565b89601f83116001146109f45791808060079897959361097f97956000936109e9575b501b916000199060031b1c19161790555b6000600285015560006003850155830160ff19815416905542613265565b600582015560068101336bffffffffffffffffffffffff60a01b82541617905501557f88aa9f9d4bbeda6aaf596730c5108c1ea969ee4fe549c51a579330a3e73777ca604051838152604085820152806109de3394604083019061301b565b0390a2604051908152f35b8c015192508e610950565b601f92919219821690846000528b6000209160005b8d8c838310610a4f5750505091839160079998969461097f98969410610a36575b5050811b019055610961565b8b015160001960f88460031b161c191690558c80610a2a565b8401518555938601939283019201610a09565b604184634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808601879052603060248201527f4d75737420686f6c6420746f6b656e7320746f2063726561746520646561637460448201526f1a5d985d1a5bdb881c1c9bdc1bdcd85b60821b6064820152608490fd5b3461035257602036600319011261035257356000526014602052602060ff604060002054166040519015158152f35b34610352576080366003190112610352576001600160401b03813581811161035257610b32903690840161305b565b6024359260443583811161035257610b4d903690830161305b565b926064359433600052610b9761059160209760008952610b736040600020541515613288565b610b7e8415156132e0565b806000526016895261058c60ff6040600020541661332c565b60115494610ba4866133b0565b601155856000526015875260406000208681556001928382018751868111610d8b57610bd4816106058454612c9c565b8a601f8211600114610d185791816007959492610c2594600091610d0d575b50600019600383901b1c191690881b1790555b600060028401556000600384015587830160ff19815416905542613265565b600582015560068101336bffffffffffffffffffffffff60a01b825416179055019381519384116107895750610c5f836106a38654612c9c565b8690601f8411600114610cac5792806106f895938193600080516020614a4683398151915298966000946107035750501b916000199060031b1c191617905560405191829133868461341d565b90601f9392931983169185600052886000209260005b8a828210610cf957505091600080516020614a4683398151915297959391856106f89896941061075c57505050811b0190556106ea565b838501518655948701949384019301610cc2565b90508b01518e610bf3565b908b8792601f198316856000528c83600020936000915b838310610d7257505050918391610c25969460079998969410610d59575b5050811b019055610c06565b8d015160001960f88460031b161c191690558e80610d4d565b84015185558b969094019392830192908101908e610d2f565b604188634e487b7160e01b6000525260246000fd5b3461035257602036600319011261035257356000526013602052602060018060a01b0360406000205416604051908152f35b3461035257604036600319011261035257610df8610dee6130a2565b6024359033613187565b602060405160018152f35b3461035257602036600319011261035257610e20602091356138b4565b604051908152f35b3461035257600036600319011261035257604051906000908054610e4b81612c9c565b80855291600191808316908115610ee55750600114610e89575b61086485610e7581870382612fd7565b60405191829160208352602083019061301b565b600090815292507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610ecd575050508101602001610e7582610864610e65565b80546020858701810191909152909301928101610eb2565b86955061086496935060209250610e7594915060ff191682840152151560051b8201019293610e65565b346103525760208060031936011261035257813533600052600082526040600020541561105c57806000526016825260ff60406000205416611018576012548114610fd45780600052601682526040600020600160ff1982541617905560175492600160401b841015610789575080610fc9610fb28560017fbba9d55e9fd1a441b1617724e2fdb76777d15ec77ab2b72ac15952cbe97085db97016017556130ed565b819391549060031b91821b91600019901b19161790565b9055604051908152a1005b60405162461bcd60e51b8152808401839052601860248201527f43616e6e6f74206164642063757272656e7420636861696e00000000000000006044820152606490fd5b60405162461bcd60e51b8152808401839052601760248201527f436861696e20616c726561647920737570706f727465640000000000000000006044820152606490fd5b60405162461bcd60e51b8152808401839052601d60248201527f4d75737420686f6c6420746f6b656e7320746f2061646420636861696e0000006044820152606490fd5b34610352576020366003190112610352576108509035613792565b346103525760209081600319360112610352578035906110da82613861565b156112e057906000915b6017548310156112b4576110f7836138b4565b92836000526016855261111160ff6040600020541661332c565b826000526015855260406000209361112b84865414613448565b61113481613831565b156112705760126007815496019560405188810191878352604082015260009780549061116082612c9c565b90600192838116908160001461123857506001146111e9575b50505090816111a7600080516020614a268339815191529594936111e298999a03601f198101835282612fd7565b5190208260005260198952604060002055546111da60405192839289846040919493926060820195825260208201520152565b0390a16133b0565b91906110e4565b9091995060005289600020988a60009a5b838c106112235750505081016060019750806111a7600080516020614a26833981519152611179565b8054858d01606001529a01998b9082016111fa565b60ff191660608087019190915283151590930285019092019a508392506111a79150600080516020614a268339815191529050611179565b60405162461bcd60e51b8152808401879052601860248201527f436861696e206e6f7420726561647920666f722073796e6300000000000000006044820152606490fd5b7f57df5a6a467271f04b10f7fe9e66d21dcd8ae7eaf079099d48959f24a53b69108483604051908152a1005b60405162461bcd60e51b815290810183905260146024820152734e6f7420616c6c20636861696e7320726561647960601b6044820152606490fd5b34610352576020366003190112610352576001600160a01b0361133c6130a2565b1660005260006020526020604060002054604051908152f35b3461035257600036600319011261035257602060ff601d54166040519015158152f35b34610352576000366003190112610352576020601254604051908152f35b346103525760203660031901126103525780610864600192359182600052601b6020526040600020906113cc82549485146149b2565b60028201549060ff60038401549184015416600584015491878060a01b036006860154169361141160078701549661140a604051809c819301612f0f565b038a612fd7565b6040519889988961313a565b346103525760403660031901126103525780359060243590336000526000602052604060002054156114a3577fd9f45b58f4c478517007ecbe71ec54f51403161f9b9e1d3c619204480321825a6040848481600052601660205261148760ff84600020541661332c565b81600052601960205280836000205582519182526020820152a1005b60849060206040519162461bcd60e51b8352820152602360248201527f4d75737420686f6c6420746f6b656e7320746f20736574206d65726b6c6520726044820152621bdbdd60ea1b6064820152fd5b34610352576020366003190112610352578035600052601b602052604060002090610864825491604051936115368561152f8160018501612f0f565b0386612fd7565b60028101549160ff60038301549183015416600583015491600760018060a01b03600686015416940154946040519889988961313a565b3461035257602036600319011261035257356000526016602052602060ff604060002054166040519015158152f35b346103525760003660031901126103525760ff6115bd81601d541615614966565b3360005260209160008352604060002054156116fb5760009160005b601c548110156116f35780600052601b855260406000208381018054918483161590816116e4575b50611617575b5050611612906133b0565b6115d9565b61162083614a0a565b90816116dc575b5015611607579250929350506001809260ff19161790555b15611687575060ff19600181601d541617601d55600f5416600f557f061e8db5c904686a2824142c80b23cd6cf492a0e068aa54080617ff53f2160ca604051914283523392a2005b6084916040519162461bcd60e51b8352820152602a60248201527f4e6f2076616c696420646561637469766174696f6e2070726f706f73616c20776044820152696974682071756f72756d60b01b6064820152fd5b905088611627565b60059150015442101588611601565b50509061163f565b60405162461bcd60e51b8152908101839052602260248201527f4d75737420686f6c6420746f6b656e7320746f206465616374697661746520446044820152614c4560f01b6064820152608490fd5b34610352576000366003190112610352576020601054604051908152f35b346103525760203660031901126103525761039260209135613831565b346103525760203660031901126103525735601754811015610352576117ac6020916130ed565b90546040519160031b1c8152f35b346103525760a03660031901126103525760643590602435908035906001600160401b03604435608435828111610352576117f8903690850161305b565b958460005260209160158352604060002097611816878a5414613448565b876000526016845261182f60ff6040600020541661332c565b60098901948860005285855260ff60406000205416611a4b578151156119fb57604051858101918983528a60408301528460608301528560808301526080825260a0820190828210908211176119e657916118e5916118ea9360405251902080938a600052601a885260406000208260005288526118b560ff60406000205416156135ba565b8b600052601988526118e0604060002054916118d2831515613606565b898082518301019101613669565b613725565b6136e2565b86600052601a8452604060002090600052835260406000209460ff199560018782541617905561191a8383613265565b600254106119a257506003886119659261195a60027fca1838d50ca3156f1ace7cde39a081cc9c9a333af6fca55db71817f8717e1dcb9c01918254613265565b905501918254613265565b90558460005252600160406000209182541617905561199d601254604051938493846040919493926060820195825260208201520152565b0390a1005b60405162461bcd60e51b8152908101849052601960248201527f566f7465732065786365656420746f74616c20737570706c79000000000000006044820152606490fd5b604189634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808801869052602360248201527f50726f6f6620726571756972656420666f722063726f73732d636861696e2073604482015262796e6360e81b6064820152608490fd5b60405162461bcd60e51b8152808801869052600e60248201526d105b1c9958591e481cde5b98d95960921b6044820152606490fd5b3461035257602036600319011261035257356000526018602052602060ff604060002054166040519015158152f35b3461035257600036600319011261035257602060405160128152f35b346103525760a0366003190112610352576001600160401b0390803582811161035257611afb903690830161305b565b6064356001600160a01b03811693604435939192919085840361035257611b486084359687600052611b4161059160209960168b5261058c60ff6040600020541661332c565b15156148a3565b8460005260148652611b6260ff60406000205416156148de565b3360005260008652611b7a6040600020541515613288565b60115494611b87866133b0565b60115585600052601587526040600020868155600191828201865185811161082057611bb7816106058454612c9c565b8a601f8211600114611d195790806007949392600091611d0e575b50600019600383901b1c191690861b1790555b611bf160243542613265565b60058401556006830180546001600160a01b031916331790556040516304fa45bf60e31b8b82015260248101919091526001600160a01b03979097166044808901919091528752601f1991611c47606489612fd7565b019386519384116107895750611c61836106a38654612c9c565b8790601f8411600114611caf5750918080926106f8969594600080516020614a46833981519152986000946107035750501b916000199060031b1c191617905560405191829133868461341d565b839692949596169185600052886000209260005b8a828210611cfa57505091600080516020614a4683398151915297959391856106f89896941061075c57505050811b0190556106ea565b838501518655948701949384019301611cc3565b90508901518d611bd2565b92919085908c601f1982168460005281600020916000905b8d838310611d6c57505050958260079710611d53575b5050811b019055611be5565b8b015160001960f88460031b161c191690558d80611d47565b8901518455978801978a959093019290810190611d31565b346103525760403660031901126103525735600052601a6020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461035257606036600319011261035257611dda6130a2565b611de26130b8565b6044359160018060a01b038116806000526001602052604060002033600052602052604060002054946000198610611e21575b5050610df89350613187565b848610611e8d578115611e75573315611e5d5750610df89484916000526001602052604060002033600052602052036040600020558480611e15565b602490600060405191634a1406b160e11b8352820152fd5b60249060006040519163e602df0560e01b8352820152fd5b60408051637dc7a0d960e11b815233928101928352602083018890529082018690529081906060010390fd5b34610352576000366003190112610352576020601c54604051908152f35b346103525760003660031901126103525760ff601d54161580611f02575b6020906040519015158152f35b50600f5460ff16611ef5565b34610352576000366003190112610352576000610120604051611f3081612fa5565b6060815260606020820152606060408201526060808201528260808201528260a0820152606060c08201528260e0820152826101008201520152604051611f7681612fa5565b604051611f868161028c81612cd6565b8152604051611f988161028c81612d7a565b6020820152604051611fad8161028c81612e01565b6040820152604051611fc28161028c81612e88565b6060820152600a546080820152600b5460a0820152600c54611fe381613652565b90611ff16040519283612fd7565b80825260208201600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c76000915b83831061215857858560c0820152600d5460e0820152600e5461010082015260ff600f54161515610120820152604051602081526120b96120a361208d6120778551610140602087015261016086019061301b565b6020860151858203601f1901604087015261301b565b6040850151848203601f1901606086015261301b565b6060840151838203601f1901608085015261301b565b608083015160a083015260a083015160c083015260c083015190601f198382030160e0840152815180825260208201916020808360051b8301019401926000915b83831061212b578680876101208b60e081015161010085015261010081015182850152015115156101408301520390f35b9091929394602080612149600193601f19868203018752895161301b565b970193019301919392906120fa565b60016020819260405161216f8161028c8189612f0f565b815201920192019190612022565b34610352576000366003190112610352576020600254604051908152f35b34610352576121a9366130ce565b6121b4929192613597565b82600052602090601b82526121d660ff604060002094610475878754146149b2565b60088301336000528083526121f360ff604060002054161561351b565b336000526000835261220b6040600020541515613557565b3360005260008352604060002054938260001461228757600201612230858254613265565b90555b3360005282526040600020600160ff1982541617905560405193845215159083015260408201527f90491c8ec6b93a0758ed2378c77e075515ecf22f312e5cca5160d1720ef3ff7760603392a26001600555005b600301612295858254613265565b9055612233565b34610352576020806003193601126103525781359182600052601582526040600020916122cb84845414613448565b818301928354926122df60ff8516156134cf565b6122e886613792565b909160058401544210801590612495575b156124415750600792916123139181612439575b506137ef565b6001948560ff19809616179055019261233b6040516123368161028c8189612f0f565b61398c565b604051948552604082860152600093805461235581612c9c565b9485604089015283821691826000146123f357505060011461239a575b7fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d286860387a1005b60009081528281209094505b8385106123df57505050508101606001817fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d28480612372565b8054868601606001529382019381016123a6565b91509150869550606093507fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d2969492501682840152151560051b82010191928480612372565b90508861230d565b60405162461bcd60e51b8152908101859052602760248201527f566f74696e67206e6f7420656e64656420616e642071756f72756d206e6f74206044820152661c995858da195960ca1b6064820152608490fd5b50816122f9565b34610352576020806003193601126103525781359033600052600081526040600020541561265a5781600052601681526124dd60ff6040600020541661332c565b60125482146126175760008281526016825260408120805460ff191690555b60178054808310156125eb57908491612514846130ed565b939054600394851b1c146125335750505061252e906133b0565b6124fc565b909192600095949519918281019081116125d657610fb2612556612562926130ed565b905490871b1c926130ed565b905581549586156125c15750807f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d596019261259c846130ed565b81939154921b1b19169055555b806000526019825260006040812055604051908152a1005b603190634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b505050907f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d592506125a9565b826064916040519162461bcd60e51b8352820152601b60248201527f43616e6e6f742072656d6f76652063757272656e7420636861696e00000000006044820152fd5b82816064926040519262461bcd60e51b845283015260248201527f4d75737420686f6c6420746f6b656e7320746f2072656d6f766520636861696e6044820152fd5b34610352576000366003190112610352576020601154604051908152f35b34610352576040366003190112610352576126d36130a2565b602435903315612741576001600160a01b0316918215611e5d5750336000526001602052604060002082600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b60405163e602df0560e01b8152600081850152602490fd5b3461035257602090816003193601126103525780359081600052601b8352604060002090612789838354146149b2565b80820190600582549361279f60ff8616156134cf565b01544210612870576127b084614a0a565b9190911561283757506127c2906137ef565b600160ff19809316179055600181601d541617601d55600f5416600f556040519081527fbd3ad027952950b28e27d2636c5535e03d64579c825a2890793333c2aec22474823392a27f061e8db5c904686a2824142c80b23cd6cf492a0e068aa54080617ff53f2160ca604051914283523392a2005b60405162461bcd60e51b81529081018690526012602482015271145d5bdc9d5b481b9bdd081c995858da195960721b6044820152606490fd5b60405162461bcd60e51b8152908101859052601060248201526f159bdd1a5b99c81b9bdd08195b99195960821b6044820152606490fd5b346103525760003660031901126103525760405160006003546128c981612c9c565b8084529060019081811690811561294e57506001146128f3575b61086484610e7581860382612fd7565b6003600090815292507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410612936575050508101602001610e75826128e3565b8054602085870181019190915290930192810161291e565b60ff191660208087019190915292151560051b85019092019250610e7591508390506128e3565b3461035257606036600319011261035257803560243590604435926001600160401b0393848111610352576129ad903690830161305b565b83600052602090601682526129c960ff6040600020541661332c565b836000526018825260ff60406000205416612ba557805115612b5057604051828101968588528660408301526822ac22a1aaaa24a7a760b91b606083015260498252608082019082821090821117612b3b57600080516020614a2683398151915297612a8b926118e592604052519020809387600052601a86526040600020826000528652612a6060ff60406000205416156135ba565b88600052601986526118e060406000205491612a7d831515613606565b878082518301019101613669565b83600052601a82526040600020906000528152601860406000209160ff19926001848254161790558460005260158152612adc60ff604060002095612ad288885414613448565b86015416156134cf565b8460005252600160406000209182541617905581815414612b1c575b5061199d601254604051938493846040919493926060820195825260208201520152565b6007612336612b359261028c6040518094819301612f0f565b83612af8565b604185634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808401839052602860248201527f50726f6f6620726571756972656420666f722063726f73732d636861696e20656044820152673c32b1baba34b7b760c11b6064820152608490fd5b60405162461bcd60e51b8152808401839052601060248201526f105b1c9958591e48195e1958dd5d195960821b6044820152606490fd5b903461035257602036600319011261035257803560005260156020526108646040600020916007835493612c1e86612c178160018501612f0f565b0387612fd7565b60028101549260ff60038301549183015416600583015491612c5760018060a01b036006860154169461152f6040518098819301612f0f565b612c73604051998a998a526101008060208c01528a019061301b565b95604089015260608801521515608087015260a086015260c085015283820360e085015261301b565b90600182811c92168015612ccc575b6020831014612cb657565b634e487b7160e01b600052602260045260246000fd5b91607f1691612cab565b60065460009291612ce682612c9c565b80825291600190818116908115612d5d5750600114612d0457505050565b9192935060066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f916000925b848410612d4557505060209250010190565b80546020858501810191909152909301928101612d33565b915050602093945060ff929192191683830152151560051b010190565b60075460009291612d8a82612c9c565b80825291600190818116908115612d5d5750600114612da857505050565b9192935060076000527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688916000925b848410612de957505060209250010190565b80546020858501810191909152909301928101612dd7565b60085460009291612e1182612c9c565b80825291600190818116908115612d5d5750600114612e2f57505050565b9192935060086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3916000925b848410612e7057505060209250010190565b80546020858501810191909152909301928101612e5e565b60095460009291612e9882612c9c565b80825291600190818116908115612d5d5750600114612eb657505050565b9192935060096000527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af916000925b848410612ef757505060209250010190565b80546020858501810191909152909301928101612ee5565b9060009291805491612f2083612c9c565b918282526001938481169081600014612f825750600114612f42575b50505050565b90919394506000526020928360002092846000945b838610612f6e575050505001019038808080612f3c565b805485870183015294019385908201612f57565b9294505050602093945060ff191683830152151560051b01019038808080612f3c565b61014081019081106001600160401b03821117612fc157604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117612fc157604052565b60005b83811061300b5750506000910152565b8181015183820152602001612ffb565b9060209161303481518092818552858086019101612ff8565b601f01601f1916010190565b6001600160401b038111612fc157601f01601f191660200190565b81601f820112156103525780359061307282613040565b926130806040519485612fd7565b8284526020838301011161035257816000926020809301838601378301015290565b600435906001600160a01b038216820361035257565b602435906001600160a01b038216820361035257565b6040906003190112610352576004359060243580151581036103525790565b6017548110156131245760176000527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b634e487b7160e01b600052603260045260246000fd5b949161315c9060e097949a99989592875261010080602089015287019061301b565b604086019990995260608501521515608084015260a08301526001600160a01b031660c08201520152565b916001600160a01b0380841692831561324c57169283156132335760009083825281602052604082205490838210613201575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b9190820180921161327257565b634e487b7160e01b600052601160045260246000fd5b1561328f57565b60405162461bcd60e51b815260206004820152602360248201527f4d75737420686f6c6420746f6b656e7320746f206372656174652070726f706f6044820152621cd85b60ea1b6064820152608490fd5b156132e757565b60405162461bcd60e51b815260206004820152601960248201527f4475726174696f6e206d75737420626520706f736974697665000000000000006044820152606490fd5b1561333357565b60405162461bcd60e51b815260206004820152601360248201527210da185a5b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606490fd5b1561337557565b60405162461bcd60e51b8152602060048201526013602482015272436861696e206e6f7420617661696c61626c6560681b6044820152606490fd5b60001981146132725760010190565b8181106133ca575050565b600081556001016133bf565b9190601f81116133e557505050565b613411926000526020600020906020601f840160051c83019310613413575b601f0160051c01906133bf565b565b9091508190613404565b9081526001600160a01b0390911660208201526060604082018190526134459291019061301b565b90565b1561344f57565b60405162461bcd60e51b815260206004820152601760248201527f50726f706f73616c20646f6573206e6f742065786973740000000000000000006044820152606490fd5b1561349b57565b60405162461bcd60e51b815260206004820152600c60248201526b159bdd1a5b99c8195b99195960a21b6044820152606490fd5b156134d657565b60405162461bcd60e51b815260206004820152601960248201527f50726f706f73616c20616c7265616479206578656375746564000000000000006044820152606490fd5b1561352257565b60405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b6044820152606490fd5b1561355e57565b60405162461bcd60e51b81526020600482015260116024820152704e6f20746f6b656e7320746f20766f746560781b6044820152606490fd5b6002600554146135a8576002600555565b604051633ee5aeb560e01b8152600490fd5b156135c157565b60405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c72656164792070726f6365737365640000000000000000006044820152606490fd5b1561360d57565b60405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c6520726f6f74206e6f742073657420666f7220636861696e0000006044820152606490fd5b6001600160401b038111612fc15760051b60200190565b6020908181840312610352578051906001600160401b03821161035257019180601f8401121561035257825161369e81613652565b936136ac6040519586612fd7565b818552838086019260051b820101928311610352578301905b8282106136d3575050505090565b815181529083019083016136c5565b156136e957565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b2b935b63290383937b7b360611b6044820152606490fd5b9091906000915b8151831015613778576020808460051b8401015191600083821060001461376757506000525261376160406000205b926133b0565b9161372c565b90604092613761948352522061375b565b9150501490565b8181029291811591840414171561327257565b908160005260156020526137ad604060002092835414613448565b60036002830154920154916137c28382613265565b60646137d36002546010549061377f565b041115928391826137e5575b50509190565b11905038806137df565b156137f657565b60405162461bcd60e51b8152602060048201526013602482015272141c9bdc1bdcd85b081b9bdd081c185cdcd959606a1b6044820152606490fd5b600052601660205260ff604060002054161561385c5760196020526040600020541561385c57600190565b600090565b61387a6000918083526015602052604083205414613448565b80601754915b82811061388f57505050600190565b61389b61058c826138b4565b156138ae576138a9906133b0565b613880565b50905090565b6017548110156138d1576138c7906130ed565b90549060031b1c90565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c6d0c2d2dc40d2dcc8caf606b1b6044820152606490fd5b9092919261391981613040565b916139276040519384612fd7565b829482845282820111610352576020613411930190612ff8565b51906001600160a01b038216820361035257565b9080601f830112156103525781516134459260200161390c565b919082604091031261035257602061398683613941565b92015190565b80518101604082602083019203126103525760208201516001600160e01b031981169290839003610352576040810151906001600160401b03821161035257019080603f830112156103525760208201516139e99260400161390c565b9063a9059cbb60e01b8103613a1f5750613a0f816020806134119451830101910161396f565b906001600160a01b031633613187565b6340c10f1960e01b8103613aa1575080602080613a419351830101910161396f565b6001600160a01b03909116908115613233577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602082613a85600094600254613265565b60025584845283825260408420818154019055604051908152a3565b632770a7eb60e21b8103613b5c575080602080613ac39351830101910161396f565b906001600160a01b0316801561324c57600091818352826020526040832054818110613b2c57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b60405163391434e360e21b81526001600160a01b0384166004820152602481019190915260448101829052606490fd5b630236fce560e51b81036145a85750908151820191610100818403126103525760208101516001600160401b03811161035257613ba190602080860191840101613955565b60408201516001600160401b03811161035257613bc690602080870191850101613955565b9360608301516001600160401b03811161035257613bec90602080840191860101613955565b9060808401516001600160401b03811161035257613c1290602080840191870101613955565b9560a08501519260c08601519160e0870151966001600160401b0388116103525760208501603f898301011215610352576020888201015194613c5486613652565b95613c626040519788612fd7565b80875260208701809a6020840160408460051b83880101011161035257604081860101915b60408460051b83880101018310614571575050505050610100015195805115614535578151156144f7578251156144b257851561447657831561444157861561440e5780516001600160401b038111612fc157613ce5600654612c9c565b601f81116143bf575b50806020601f821160011461433b57600091614330575b508160011b916000199060031b1c1916176006555b81516001600160401b038111612fc157613d35600754612c9c565b601f81116142e1575b50806020601f821160011461425d57600091614252575b508160011b916000199060031b1c1916176007555b82516001600160401b038111612fc157613d85600854612c9c565b601f8111614203575b50806020601f821160011461417f57600091614174575b508160011b916000199060031b1c1916176008555b89516001600160401b038111612fc157613dd5600954612c9c565b601f8111614125575b50806020601f821160011461409e57600091614093575b508160011b916000199060031b1c1916176009555b85600a5583600b558451600160401b8111612fc157600c5481600c55808210614001575b508890600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7916000905b828210613f215750505050613e8e926103156101009a9b93610307610323948b600d556040519d8e818152019061301b565b92608087015260a086015284820360c086015251808252602082019160208260051b82010194926000915b838310613ef45750505050509180917f62d6efdb8dbca656ac38d327c1d66a4ccaeabc91c464fe5e7352b604858f5f469360e08301520390a1565b9091929395602080613f12600193601f198682030187528a5161301b565b98019301930191939290613eb9565b80518051906001600160401b038211612fc157613f4882613f428854612c9c565b886133d6565b602090601f8311600114613f94579282600194936020938695600092613f89575b5050600019600383901b1c191690841b1787555b01940191019092613e5c565b015190503880613f69565b90601f198316918760005260206000209260005b818110613fe9575092600195928592879660209610613fd0575b505050831b83018755613f7d565b015160001960f88460031b161c19169055388080613fc2565b92936020600181928786015181550195019301613fa8565b600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7908282015b818301811061403c575050613e2e565b8061404960019254612c9c565b80614056575b500161402c565b601f8111831461406c5750600081555b3861404f565b60009082825261408a601f60208420920160051c82018583016133bf565b81835555614066565b90508b015138613df5565b600960009081527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9250601f198416908e5b82821061410c57505090836001949392106140f3575b5050811b01600955613e0a565b8d015160001960f88460031b161c1916905538806140e6565b600184956020939584930151815501940192018e6140d0565b61416e9060096000527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af601f840160051c8101916020851061341357601f0160051c01906133bf565b38613dde565b905084015138613da5565b600860009081527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39250601f198416905b8181106141eb575090836001949392106141d2575b5050811b01600855613dba565b86015160001960f88460031b161c1916905538806141c5565b9192602060018192868b0151815501940192016141b0565b61424c9060086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3601f840160051c8101916020851061341357601f0160051c01906133bf565b38613d8e565b905083015138613d55565b600760009081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889250601f198416905b8181106142c9575090836001949392106142b0575b5050811b01600755613d6a565b85015160001960f88460031b161c1916905538806142a3565b9192602060018192868a01518155019401920161428e565b61432a9060076000527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688601f840160051c8101916020851061341357601f0160051c01906133bf565b38613d3e565b905082015138613d05565b600660009081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f9250601f198416905b8181106143a75750908360019493921061438e575b5050811b01600655613d1a565b84015160001960f88460031b161c191690553880614381565b9192602060018192868901518155019401920161436c565b6144089060066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f601f840160051c8101916020851061341357601f0160051c01906133bf565b38613cee565b60405162461bcd60e51b815260206004820152600b60248201526a0496e76616c6964204b50560ac1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964204f4b544d4f60981b6044820152606490fd5b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b210353ab934b9b234b1ba34b7b760611b6044820152606490fd5b60405162461bcd60e51b815260206004820152601860248201527f4c6f636174696f6e2063616e6e6f7420626520656d70747900000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527553796d626f6c2063616e6e6f7420626520656d70747960501b6044820152606490fd5b60405162461bcd60e51b81526020600482015260146024820152734e616d652063616e6e6f7420626520656d70747960601b6044820152606490fd5b8251906001600160401b038211610352576020809161459b60409485848b0191888d010101613955565b8152019301929050613c87565b63f0f9e6b760e01b810361465f5750602081805181010312610352576020015180151580614654575b1561460f5760407fd0198ea88bf9c4ad5317b68e697944e524541fcb494d854f095b1cd88a097ab691601054908060105582519182526020820152a1565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642071756f72756d2070657263656e74616765000000000000006044820152606490fd5b5060648111156145d1565b632ab43f7f60e11b810361470f5750602081805181010312610352576020015180600052601660205261469960ff6040600020541661332c565b601254908181146146da577f979103c7afbf0138fe781172504ceb318ff78f9a420de8cabac8141f0121b521918160409260125582519182526020820152a1565b60405162461bcd60e51b815260206004820152600d60248201526c14d85b594818da185a5b881251609a1b6044820152606490fd5b6304fa45bf60e31b81036147dd57506040818051810103126103525760208101517ff14475b19484bf096265507cc0c41cd3bf1994992088806830686e2d72722719916001600160a01b039061476790604001613941565b16906147748215156148a3565b80600052601460205261478f60ff60406000205416156148de565b600081815260136020908152604080832080546001600160a01b031916861790556014825291829020805460ff1916600117905581519283526001600160a01b0390931692820192909252a1565b633972e9fb60e21b0361486a57602081805181010312610352576020807f4c7c76abe482a2c36ea52f1b999474c69f8b4afeeac5635f8aea2526864ba853920151806000526014825261483760ff60406000205416614922565b600081815260138352604080822080546001600160a01b03191690556014845290819020805460ff1916905551908152a1565b60405162461bcd60e51b81526020600482015260116024820152702ab735b737bbb71037b832b930ba34b7b760791b6044820152606490fd5b156148aa57565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b156148e557565b60405162461bcd60e51b81526020600482015260156024820152744d6f64756c6520616c72656164792065786973747360581b6044820152606490fd5b1561492957565b60405162461bcd60e51b8152602060048201526015602482015274135bd91d5b1948191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606490fd5b1561496d57565b60405162461bcd60e51b815260206004820152601760248201527f444c4520616c72656164792064656163746976617465640000000000000000006044820152606490fd5b156149b957565b60405162461bcd60e51b8152602060048201526024808201527f446561637469766174696f6e2070726f706f73616c20646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608490fd5b9081600052601b6020526137ad6040600020928354146149b256fe42e60114b8bc5803b43a4bcd35572ece9a5e2cabb79a838a02d56a4c53e833137585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd63a2646970667358221220c6e394d53611307294b6f8aac07316f9cb25a290fe9ad141368264da25827d2064736f6c63430008140033", - "deployedBytecode": "0x60808060405260048036101561001457600080fd5b60003560e01c918263013cf08b14612bdc57508163044bc2bd1461297557816306fdde03146128a75781630933fad414612759578163095ea7b3146126ba5781630c0512e91461269c5781630c4844aa1461249c5781630d61b5191461229c5781631552d75c1461219b57816318160ddd1461217d578163204c5d1f14611f0e57816322dbefbb14610da057816322f3e2d414611ed75781632388b53114611eb957816323b872dd14611dc15781632441d76f14611d845781632519ae5c14611acb578163313ce56714611aaf5781633b60288a14611a80578163456d10c1146117ba5781634b14579314610ad45781634cf2ab32146117855781634de184f6146117685781634fa76ec91461174a57816351b42b001461159c5781635221c1f01461156d578163548d496f1461156d578163553b527a146114f3578163560cada51461141d5781635cf0e8a4146113785781635d57d260146113965781636cbadbfa146113785781636dcf811d1461135557816370a082311461131b5781637481c8e91461039c5781637ce288ea146110bb5781637e5a9b47146110a057816387188a0014610f0f57816395d89b4114610e285781639a49bdde14610e03578163a9059cbb14610dd2578163b0b6cc1a14610da0578163b359451014610b03578163b3fe8bcb14610ad4578163b5b353be14610868578163bc62f34e14610835578163c9a3c0c714610532578163c9d27afe14610417578163dd62ed3e146103c6578163e1605aa21461039c578163e49a62e91461037557508063eced3dfb146103575763f2c26a471461026857600080fd5b34610352576000366003190112610352576103076040516102938161028c81612cd6565b0382612fd7565b6040516102a38161028c81612d7a565b604051906102bb826102b481612e01565b0383612fd7565b604051916102d3836102cc81612e88565b0384612fd7565b600a5492600b54610331600d5492610323600e549561031560ff600f5416986040519c8d9c8d61012090818152019061301b565b8c810360208e01529061301b565b908a820360408c015261301b565b9088820360608a015261301b565b94608087015260a086015260c085015260e084015215156101008301520390f35b600080fd5b34610352576000366003190112610352576020601754604051908152f35b346103525760203660031901126103525761039260209135613861565b6040519015158152f35b34610352576020366003190112610352573560005260196020526020604060002054604051908152f35b34610352576040366003190112610352576103df6130a2565b6103e76130b8565b9060018060a01b038091166000526001602052604060002091166000526020526020604060002054604051908152f35b346103525760807f78975aaf742630489badd22949b88ac50eaaea576339ee05440b671a33bfb6a991610449366130ce565b610454929192613597565b8260005260206015815261048e60ff60406000209461047587875414613448565b61048460058701544210613494565b85015416156134cf565b6008830192336000528382526104ac60ff604060002054161561351b565b33600052600082526104c46040600020541515613557565b33600052600082526040600020549382526040600020600160ff198254161790558260001461051d576002016104fb848254613265565b90555b6040519384523390840152151560408301526060820152a16001600555005b60030161052b848254613265565b90556104fe565b34610352576080366003190112610352576001600160401b0390803582811161035257610562903690830161305b565b6044359160643593846000526105966105916020966016885261058c60ff6040600020541661332c565b613831565b61336e565b83600052601485526105af60ff60406000205416614922565b33600052600085526105c76040600020541515613288565b601154936105d4856133b0565b601155846000526015865260406000209085825560019182810186518581116108205761060b816106058454612c9c565b846133d6565b808a601f82116001146107be576000916107b3575b50600019600383901b1c191690851b1790555b61063f60243542613265565b60058201556006810180546001600160a01b03191633179055604051633972e9fb60e21b89820152602480820193909352918252606082018481118382101761079e57906007916040520193815193841161078957506106a9836106a38654612c9c565b866133d6565b8690601f841160011461070e5792806106f895938193600080516020614a468339815191529896600094610703575b50501b916000199060031b1c19161790555b60405191829133868461341d565b0390a1604051908152f35b015192508a806106d8565b90601f9392931983169185600052886000209260005b8a82821061077557505091600080516020614a4683398151915297959391856106f89896941061075c575b505050811b0190556106ea565b015160001960f88460031b161c1916905588808061074f565b838501518655948701949384019301610724565b604190634e487b7160e01b6000525260246000fd5b604186634e487b7160e01b6000525260246000fd5b90508801518b610620565b60008481528c81208894509190601f198416908e5b8d83831061080a5750505083116107f1575b5050811b019055610633565b8a015160001960f88460031b161c191690558b806107e5565b84015185558a969094019392830192018e6107d3565b604187634e487b7160e01b6000525260246000fd5b34610352576020366003190112610352576108509035614a0a565b604080519215158352901515602083015290f35b0390f35b34610352576060366003190112610352576001600160401b0390803582811161035257610898903690830161305b565b60243592604435906108af60ff601d541615614966565b336000526020946000865260406000205415610a77576108d08115156132e0565b82600052601686526108e960ff6040600020541661332c565b601c54946108f6866133b0565b601c5585600052601b8752604060002092868455600190818501918751918211610a625761092e826109288554612c9c565b856133d6565b89601f83116001146109f45791808060079897959361097f97956000936109e9575b501b916000199060031b1c19161790555b6000600285015560006003850155830160ff19815416905542613265565b600582015560068101336bffffffffffffffffffffffff60a01b82541617905501557f88aa9f9d4bbeda6aaf596730c5108c1ea969ee4fe549c51a579330a3e73777ca604051838152604085820152806109de3394604083019061301b565b0390a2604051908152f35b8c015192508e610950565b601f92919219821690846000528b6000209160005b8d8c838310610a4f5750505091839160079998969461097f98969410610a36575b5050811b019055610961565b8b015160001960f88460031b161c191690558c80610a2a565b8401518555938601939283019201610a09565b604184634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808601879052603060248201527f4d75737420686f6c6420746f6b656e7320746f2063726561746520646561637460448201526f1a5d985d1a5bdb881c1c9bdc1bdcd85b60821b6064820152608490fd5b3461035257602036600319011261035257356000526014602052602060ff604060002054166040519015158152f35b34610352576080366003190112610352576001600160401b03813581811161035257610b32903690840161305b565b6024359260443583811161035257610b4d903690830161305b565b926064359433600052610b9761059160209760008952610b736040600020541515613288565b610b7e8415156132e0565b806000526016895261058c60ff6040600020541661332c565b60115494610ba4866133b0565b601155856000526015875260406000208681556001928382018751868111610d8b57610bd4816106058454612c9c565b8a601f8211600114610d185791816007959492610c2594600091610d0d575b50600019600383901b1c191690881b1790555b600060028401556000600384015587830160ff19815416905542613265565b600582015560068101336bffffffffffffffffffffffff60a01b825416179055019381519384116107895750610c5f836106a38654612c9c565b8690601f8411600114610cac5792806106f895938193600080516020614a4683398151915298966000946107035750501b916000199060031b1c191617905560405191829133868461341d565b90601f9392931983169185600052886000209260005b8a828210610cf957505091600080516020614a4683398151915297959391856106f89896941061075c57505050811b0190556106ea565b838501518655948701949384019301610cc2565b90508b01518e610bf3565b908b8792601f198316856000528c83600020936000915b838310610d7257505050918391610c25969460079998969410610d59575b5050811b019055610c06565b8d015160001960f88460031b161c191690558e80610d4d565b84015185558b969094019392830192908101908e610d2f565b604188634e487b7160e01b6000525260246000fd5b3461035257602036600319011261035257356000526013602052602060018060a01b0360406000205416604051908152f35b3461035257604036600319011261035257610df8610dee6130a2565b6024359033613187565b602060405160018152f35b3461035257602036600319011261035257610e20602091356138b4565b604051908152f35b3461035257600036600319011261035257604051906000908054610e4b81612c9c565b80855291600191808316908115610ee55750600114610e89575b61086485610e7581870382612fd7565b60405191829160208352602083019061301b565b600090815292507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610ecd575050508101602001610e7582610864610e65565b80546020858701810191909152909301928101610eb2565b86955061086496935060209250610e7594915060ff191682840152151560051b8201019293610e65565b346103525760208060031936011261035257813533600052600082526040600020541561105c57806000526016825260ff60406000205416611018576012548114610fd45780600052601682526040600020600160ff1982541617905560175492600160401b841015610789575080610fc9610fb28560017fbba9d55e9fd1a441b1617724e2fdb76777d15ec77ab2b72ac15952cbe97085db97016017556130ed565b819391549060031b91821b91600019901b19161790565b9055604051908152a1005b60405162461bcd60e51b8152808401839052601860248201527f43616e6e6f74206164642063757272656e7420636861696e00000000000000006044820152606490fd5b60405162461bcd60e51b8152808401839052601760248201527f436861696e20616c726561647920737570706f727465640000000000000000006044820152606490fd5b60405162461bcd60e51b8152808401839052601d60248201527f4d75737420686f6c6420746f6b656e7320746f2061646420636861696e0000006044820152606490fd5b34610352576020366003190112610352576108509035613792565b346103525760209081600319360112610352578035906110da82613861565b156112e057906000915b6017548310156112b4576110f7836138b4565b92836000526016855261111160ff6040600020541661332c565b826000526015855260406000209361112b84865414613448565b61113481613831565b156112705760126007815496019560405188810191878352604082015260009780549061116082612c9c565b90600192838116908160001461123857506001146111e9575b50505090816111a7600080516020614a268339815191529594936111e298999a03601f198101835282612fd7565b5190208260005260198952604060002055546111da60405192839289846040919493926060820195825260208201520152565b0390a16133b0565b91906110e4565b9091995060005289600020988a60009a5b838c106112235750505081016060019750806111a7600080516020614a26833981519152611179565b8054858d01606001529a01998b9082016111fa565b60ff191660608087019190915283151590930285019092019a508392506111a79150600080516020614a268339815191529050611179565b60405162461bcd60e51b8152808401879052601860248201527f436861696e206e6f7420726561647920666f722073796e6300000000000000006044820152606490fd5b7f57df5a6a467271f04b10f7fe9e66d21dcd8ae7eaf079099d48959f24a53b69108483604051908152a1005b60405162461bcd60e51b815290810183905260146024820152734e6f7420616c6c20636861696e7320726561647960601b6044820152606490fd5b34610352576020366003190112610352576001600160a01b0361133c6130a2565b1660005260006020526020604060002054604051908152f35b3461035257600036600319011261035257602060ff601d54166040519015158152f35b34610352576000366003190112610352576020601254604051908152f35b346103525760203660031901126103525780610864600192359182600052601b6020526040600020906113cc82549485146149b2565b60028201549060ff60038401549184015416600584015491878060a01b036006860154169361141160078701549661140a604051809c819301612f0f565b038a612fd7565b6040519889988961313a565b346103525760403660031901126103525780359060243590336000526000602052604060002054156114a3577fd9f45b58f4c478517007ecbe71ec54f51403161f9b9e1d3c619204480321825a6040848481600052601660205261148760ff84600020541661332c565b81600052601960205280836000205582519182526020820152a1005b60849060206040519162461bcd60e51b8352820152602360248201527f4d75737420686f6c6420746f6b656e7320746f20736574206d65726b6c6520726044820152621bdbdd60ea1b6064820152fd5b34610352576020366003190112610352578035600052601b602052604060002090610864825491604051936115368561152f8160018501612f0f565b0386612fd7565b60028101549160ff60038301549183015416600583015491600760018060a01b03600686015416940154946040519889988961313a565b3461035257602036600319011261035257356000526016602052602060ff604060002054166040519015158152f35b346103525760003660031901126103525760ff6115bd81601d541615614966565b3360005260209160008352604060002054156116fb5760009160005b601c548110156116f35780600052601b855260406000208381018054918483161590816116e4575b50611617575b5050611612906133b0565b6115d9565b61162083614a0a565b90816116dc575b5015611607579250929350506001809260ff19161790555b15611687575060ff19600181601d541617601d55600f5416600f557f061e8db5c904686a2824142c80b23cd6cf492a0e068aa54080617ff53f2160ca604051914283523392a2005b6084916040519162461bcd60e51b8352820152602a60248201527f4e6f2076616c696420646561637469766174696f6e2070726f706f73616c20776044820152696974682071756f72756d60b01b6064820152fd5b905088611627565b60059150015442101588611601565b50509061163f565b60405162461bcd60e51b8152908101839052602260248201527f4d75737420686f6c6420746f6b656e7320746f206465616374697661746520446044820152614c4560f01b6064820152608490fd5b34610352576000366003190112610352576020601054604051908152f35b346103525760203660031901126103525761039260209135613831565b346103525760203660031901126103525735601754811015610352576117ac6020916130ed565b90546040519160031b1c8152f35b346103525760a03660031901126103525760643590602435908035906001600160401b03604435608435828111610352576117f8903690850161305b565b958460005260209160158352604060002097611816878a5414613448565b876000526016845261182f60ff6040600020541661332c565b60098901948860005285855260ff60406000205416611a4b578151156119fb57604051858101918983528a60408301528460608301528560808301526080825260a0820190828210908211176119e657916118e5916118ea9360405251902080938a600052601a885260406000208260005288526118b560ff60406000205416156135ba565b8b600052601988526118e0604060002054916118d2831515613606565b898082518301019101613669565b613725565b6136e2565b86600052601a8452604060002090600052835260406000209460ff199560018782541617905561191a8383613265565b600254106119a257506003886119659261195a60027fca1838d50ca3156f1ace7cde39a081cc9c9a333af6fca55db71817f8717e1dcb9c01918254613265565b905501918254613265565b90558460005252600160406000209182541617905561199d601254604051938493846040919493926060820195825260208201520152565b0390a1005b60405162461bcd60e51b8152908101849052601960248201527f566f7465732065786365656420746f74616c20737570706c79000000000000006044820152606490fd5b604189634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808801869052602360248201527f50726f6f6620726571756972656420666f722063726f73732d636861696e2073604482015262796e6360e81b6064820152608490fd5b60405162461bcd60e51b8152808801869052600e60248201526d105b1c9958591e481cde5b98d95960921b6044820152606490fd5b3461035257602036600319011261035257356000526018602052602060ff604060002054166040519015158152f35b3461035257600036600319011261035257602060405160128152f35b346103525760a0366003190112610352576001600160401b0390803582811161035257611afb903690830161305b565b6064356001600160a01b03811693604435939192919085840361035257611b486084359687600052611b4161059160209960168b5261058c60ff6040600020541661332c565b15156148a3565b8460005260148652611b6260ff60406000205416156148de565b3360005260008652611b7a6040600020541515613288565b60115494611b87866133b0565b60115585600052601587526040600020868155600191828201865185811161082057611bb7816106058454612c9c565b8a601f8211600114611d195790806007949392600091611d0e575b50600019600383901b1c191690861b1790555b611bf160243542613265565b60058401556006830180546001600160a01b031916331790556040516304fa45bf60e31b8b82015260248101919091526001600160a01b03979097166044808901919091528752601f1991611c47606489612fd7565b019386519384116107895750611c61836106a38654612c9c565b8790601f8411600114611caf5750918080926106f8969594600080516020614a46833981519152986000946107035750501b916000199060031b1c191617905560405191829133868461341d565b839692949596169185600052886000209260005b8a828210611cfa57505091600080516020614a4683398151915297959391856106f89896941061075c57505050811b0190556106ea565b838501518655948701949384019301611cc3565b90508901518d611bd2565b92919085908c601f1982168460005281600020916000905b8d838310611d6c57505050958260079710611d53575b5050811b019055611be5565b8b015160001960f88460031b161c191690558d80611d47565b8901518455978801978a959093019290810190611d31565b346103525760403660031901126103525735600052601a6020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461035257606036600319011261035257611dda6130a2565b611de26130b8565b6044359160018060a01b038116806000526001602052604060002033600052602052604060002054946000198610611e21575b5050610df89350613187565b848610611e8d578115611e75573315611e5d5750610df89484916000526001602052604060002033600052602052036040600020558480611e15565b602490600060405191634a1406b160e11b8352820152fd5b60249060006040519163e602df0560e01b8352820152fd5b60408051637dc7a0d960e11b815233928101928352602083018890529082018690529081906060010390fd5b34610352576000366003190112610352576020601c54604051908152f35b346103525760003660031901126103525760ff601d54161580611f02575b6020906040519015158152f35b50600f5460ff16611ef5565b34610352576000366003190112610352576000610120604051611f3081612fa5565b6060815260606020820152606060408201526060808201528260808201528260a0820152606060c08201528260e0820152826101008201520152604051611f7681612fa5565b604051611f868161028c81612cd6565b8152604051611f988161028c81612d7a565b6020820152604051611fad8161028c81612e01565b6040820152604051611fc28161028c81612e88565b6060820152600a546080820152600b5460a0820152600c54611fe381613652565b90611ff16040519283612fd7565b80825260208201600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c76000915b83831061215857858560c0820152600d5460e0820152600e5461010082015260ff600f54161515610120820152604051602081526120b96120a361208d6120778551610140602087015261016086019061301b565b6020860151858203601f1901604087015261301b565b6040850151848203601f1901606086015261301b565b6060840151838203601f1901608085015261301b565b608083015160a083015260a083015160c083015260c083015190601f198382030160e0840152815180825260208201916020808360051b8301019401926000915b83831061212b578680876101208b60e081015161010085015261010081015182850152015115156101408301520390f35b9091929394602080612149600193601f19868203018752895161301b565b970193019301919392906120fa565b60016020819260405161216f8161028c8189612f0f565b815201920192019190612022565b34610352576000366003190112610352576020600254604051908152f35b34610352576121a9366130ce565b6121b4929192613597565b82600052602090601b82526121d660ff604060002094610475878754146149b2565b60088301336000528083526121f360ff604060002054161561351b565b336000526000835261220b6040600020541515613557565b3360005260008352604060002054938260001461228757600201612230858254613265565b90555b3360005282526040600020600160ff1982541617905560405193845215159083015260408201527f90491c8ec6b93a0758ed2378c77e075515ecf22f312e5cca5160d1720ef3ff7760603392a26001600555005b600301612295858254613265565b9055612233565b34610352576020806003193601126103525781359182600052601582526040600020916122cb84845414613448565b818301928354926122df60ff8516156134cf565b6122e886613792565b909160058401544210801590612495575b156124415750600792916123139181612439575b506137ef565b6001948560ff19809616179055019261233b6040516123368161028c8189612f0f565b61398c565b604051948552604082860152600093805461235581612c9c565b9485604089015283821691826000146123f357505060011461239a575b7fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d286860387a1005b60009081528281209094505b8385106123df57505050508101606001817fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d28480612372565b8054868601606001529382019381016123a6565b91509150869550606093507fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d2969492501682840152151560051b82010191928480612372565b90508861230d565b60405162461bcd60e51b8152908101859052602760248201527f566f74696e67206e6f7420656e64656420616e642071756f72756d206e6f74206044820152661c995858da195960ca1b6064820152608490fd5b50816122f9565b34610352576020806003193601126103525781359033600052600081526040600020541561265a5781600052601681526124dd60ff6040600020541661332c565b60125482146126175760008281526016825260408120805460ff191690555b60178054808310156125eb57908491612514846130ed565b939054600394851b1c146125335750505061252e906133b0565b6124fc565b909192600095949519918281019081116125d657610fb2612556612562926130ed565b905490871b1c926130ed565b905581549586156125c15750807f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d596019261259c846130ed565b81939154921b1b19169055555b806000526019825260006040812055604051908152a1005b603190634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b505050907f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d592506125a9565b826064916040519162461bcd60e51b8352820152601b60248201527f43616e6e6f742072656d6f76652063757272656e7420636861696e00000000006044820152fd5b82816064926040519262461bcd60e51b845283015260248201527f4d75737420686f6c6420746f6b656e7320746f2072656d6f766520636861696e6044820152fd5b34610352576000366003190112610352576020601154604051908152f35b34610352576040366003190112610352576126d36130a2565b602435903315612741576001600160a01b0316918215611e5d5750336000526001602052604060002082600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b60405163e602df0560e01b8152600081850152602490fd5b3461035257602090816003193601126103525780359081600052601b8352604060002090612789838354146149b2565b80820190600582549361279f60ff8616156134cf565b01544210612870576127b084614a0a565b9190911561283757506127c2906137ef565b600160ff19809316179055600181601d541617601d55600f5416600f556040519081527fbd3ad027952950b28e27d2636c5535e03d64579c825a2890793333c2aec22474823392a27f061e8db5c904686a2824142c80b23cd6cf492a0e068aa54080617ff53f2160ca604051914283523392a2005b60405162461bcd60e51b81529081018690526012602482015271145d5bdc9d5b481b9bdd081c995858da195960721b6044820152606490fd5b60405162461bcd60e51b8152908101859052601060248201526f159bdd1a5b99c81b9bdd08195b99195960821b6044820152606490fd5b346103525760003660031901126103525760405160006003546128c981612c9c565b8084529060019081811690811561294e57506001146128f3575b61086484610e7581860382612fd7565b6003600090815292507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410612936575050508101602001610e75826128e3565b8054602085870181019190915290930192810161291e565b60ff191660208087019190915292151560051b85019092019250610e7591508390506128e3565b3461035257606036600319011261035257803560243590604435926001600160401b0393848111610352576129ad903690830161305b565b83600052602090601682526129c960ff6040600020541661332c565b836000526018825260ff60406000205416612ba557805115612b5057604051828101968588528660408301526822ac22a1aaaa24a7a760b91b606083015260498252608082019082821090821117612b3b57600080516020614a2683398151915297612a8b926118e592604052519020809387600052601a86526040600020826000528652612a6060ff60406000205416156135ba565b88600052601986526118e060406000205491612a7d831515613606565b878082518301019101613669565b83600052601a82526040600020906000528152601860406000209160ff19926001848254161790558460005260158152612adc60ff604060002095612ad288885414613448565b86015416156134cf565b8460005252600160406000209182541617905581815414612b1c575b5061199d601254604051938493846040919493926060820195825260208201520152565b6007612336612b359261028c6040518094819301612f0f565b83612af8565b604185634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808401839052602860248201527f50726f6f6620726571756972656420666f722063726f73732d636861696e20656044820152673c32b1baba34b7b760c11b6064820152608490fd5b60405162461bcd60e51b8152808401839052601060248201526f105b1c9958591e48195e1958dd5d195960821b6044820152606490fd5b903461035257602036600319011261035257803560005260156020526108646040600020916007835493612c1e86612c178160018501612f0f565b0387612fd7565b60028101549260ff60038301549183015416600583015491612c5760018060a01b036006860154169461152f6040518098819301612f0f565b612c73604051998a998a526101008060208c01528a019061301b565b95604089015260608801521515608087015260a086015260c085015283820360e085015261301b565b90600182811c92168015612ccc575b6020831014612cb657565b634e487b7160e01b600052602260045260246000fd5b91607f1691612cab565b60065460009291612ce682612c9c565b80825291600190818116908115612d5d5750600114612d0457505050565b9192935060066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f916000925b848410612d4557505060209250010190565b80546020858501810191909152909301928101612d33565b915050602093945060ff929192191683830152151560051b010190565b60075460009291612d8a82612c9c565b80825291600190818116908115612d5d5750600114612da857505050565b9192935060076000527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688916000925b848410612de957505060209250010190565b80546020858501810191909152909301928101612dd7565b60085460009291612e1182612c9c565b80825291600190818116908115612d5d5750600114612e2f57505050565b9192935060086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3916000925b848410612e7057505060209250010190565b80546020858501810191909152909301928101612e5e565b60095460009291612e9882612c9c565b80825291600190818116908115612d5d5750600114612eb657505050565b9192935060096000527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af916000925b848410612ef757505060209250010190565b80546020858501810191909152909301928101612ee5565b9060009291805491612f2083612c9c565b918282526001938481169081600014612f825750600114612f42575b50505050565b90919394506000526020928360002092846000945b838610612f6e575050505001019038808080612f3c565b805485870183015294019385908201612f57565b9294505050602093945060ff191683830152151560051b01019038808080612f3c565b61014081019081106001600160401b03821117612fc157604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117612fc157604052565b60005b83811061300b5750506000910152565b8181015183820152602001612ffb565b9060209161303481518092818552858086019101612ff8565b601f01601f1916010190565b6001600160401b038111612fc157601f01601f191660200190565b81601f820112156103525780359061307282613040565b926130806040519485612fd7565b8284526020838301011161035257816000926020809301838601378301015290565b600435906001600160a01b038216820361035257565b602435906001600160a01b038216820361035257565b6040906003190112610352576004359060243580151581036103525790565b6017548110156131245760176000527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b634e487b7160e01b600052603260045260246000fd5b949161315c9060e097949a99989592875261010080602089015287019061301b565b604086019990995260608501521515608084015260a08301526001600160a01b031660c08201520152565b916001600160a01b0380841692831561324c57169283156132335760009083825281602052604082205490838210613201575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b9190820180921161327257565b634e487b7160e01b600052601160045260246000fd5b1561328f57565b60405162461bcd60e51b815260206004820152602360248201527f4d75737420686f6c6420746f6b656e7320746f206372656174652070726f706f6044820152621cd85b60ea1b6064820152608490fd5b156132e757565b60405162461bcd60e51b815260206004820152601960248201527f4475726174696f6e206d75737420626520706f736974697665000000000000006044820152606490fd5b1561333357565b60405162461bcd60e51b815260206004820152601360248201527210da185a5b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606490fd5b1561337557565b60405162461bcd60e51b8152602060048201526013602482015272436861696e206e6f7420617661696c61626c6560681b6044820152606490fd5b60001981146132725760010190565b8181106133ca575050565b600081556001016133bf565b9190601f81116133e557505050565b613411926000526020600020906020601f840160051c83019310613413575b601f0160051c01906133bf565b565b9091508190613404565b9081526001600160a01b0390911660208201526060604082018190526134459291019061301b565b90565b1561344f57565b60405162461bcd60e51b815260206004820152601760248201527f50726f706f73616c20646f6573206e6f742065786973740000000000000000006044820152606490fd5b1561349b57565b60405162461bcd60e51b815260206004820152600c60248201526b159bdd1a5b99c8195b99195960a21b6044820152606490fd5b156134d657565b60405162461bcd60e51b815260206004820152601960248201527f50726f706f73616c20616c7265616479206578656375746564000000000000006044820152606490fd5b1561352257565b60405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b6044820152606490fd5b1561355e57565b60405162461bcd60e51b81526020600482015260116024820152704e6f20746f6b656e7320746f20766f746560781b6044820152606490fd5b6002600554146135a8576002600555565b604051633ee5aeb560e01b8152600490fd5b156135c157565b60405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c72656164792070726f6365737365640000000000000000006044820152606490fd5b1561360d57565b60405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c6520726f6f74206e6f742073657420666f7220636861696e0000006044820152606490fd5b6001600160401b038111612fc15760051b60200190565b6020908181840312610352578051906001600160401b03821161035257019180601f8401121561035257825161369e81613652565b936136ac6040519586612fd7565b818552838086019260051b820101928311610352578301905b8282106136d3575050505090565b815181529083019083016136c5565b156136e957565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b2b935b63290383937b7b360611b6044820152606490fd5b9091906000915b8151831015613778576020808460051b8401015191600083821060001461376757506000525261376160406000205b926133b0565b9161372c565b90604092613761948352522061375b565b9150501490565b8181029291811591840414171561327257565b908160005260156020526137ad604060002092835414613448565b60036002830154920154916137c28382613265565b60646137d36002546010549061377f565b041115928391826137e5575b50509190565b11905038806137df565b156137f657565b60405162461bcd60e51b8152602060048201526013602482015272141c9bdc1bdcd85b081b9bdd081c185cdcd959606a1b6044820152606490fd5b600052601660205260ff604060002054161561385c5760196020526040600020541561385c57600190565b600090565b61387a6000918083526015602052604083205414613448565b80601754915b82811061388f57505050600190565b61389b61058c826138b4565b156138ae576138a9906133b0565b613880565b50905090565b6017548110156138d1576138c7906130ed565b90549060031b1c90565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c6d0c2d2dc40d2dcc8caf606b1b6044820152606490fd5b9092919261391981613040565b916139276040519384612fd7565b829482845282820111610352576020613411930190612ff8565b51906001600160a01b038216820361035257565b9080601f830112156103525781516134459260200161390c565b919082604091031261035257602061398683613941565b92015190565b80518101604082602083019203126103525760208201516001600160e01b031981169290839003610352576040810151906001600160401b03821161035257019080603f830112156103525760208201516139e99260400161390c565b9063a9059cbb60e01b8103613a1f5750613a0f816020806134119451830101910161396f565b906001600160a01b031633613187565b6340c10f1960e01b8103613aa1575080602080613a419351830101910161396f565b6001600160a01b03909116908115613233577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602082613a85600094600254613265565b60025584845283825260408420818154019055604051908152a3565b632770a7eb60e21b8103613b5c575080602080613ac39351830101910161396f565b906001600160a01b0316801561324c57600091818352826020526040832054818110613b2c57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b60405163391434e360e21b81526001600160a01b0384166004820152602481019190915260448101829052606490fd5b630236fce560e51b81036145a85750908151820191610100818403126103525760208101516001600160401b03811161035257613ba190602080860191840101613955565b60408201516001600160401b03811161035257613bc690602080870191850101613955565b9360608301516001600160401b03811161035257613bec90602080840191860101613955565b9060808401516001600160401b03811161035257613c1290602080840191870101613955565b9560a08501519260c08601519160e0870151966001600160401b0388116103525760208501603f898301011215610352576020888201015194613c5486613652565b95613c626040519788612fd7565b80875260208701809a6020840160408460051b83880101011161035257604081860101915b60408460051b83880101018310614571575050505050610100015195805115614535578151156144f7578251156144b257851561447657831561444157861561440e5780516001600160401b038111612fc157613ce5600654612c9c565b601f81116143bf575b50806020601f821160011461433b57600091614330575b508160011b916000199060031b1c1916176006555b81516001600160401b038111612fc157613d35600754612c9c565b601f81116142e1575b50806020601f821160011461425d57600091614252575b508160011b916000199060031b1c1916176007555b82516001600160401b038111612fc157613d85600854612c9c565b601f8111614203575b50806020601f821160011461417f57600091614174575b508160011b916000199060031b1c1916176008555b89516001600160401b038111612fc157613dd5600954612c9c565b601f8111614125575b50806020601f821160011461409e57600091614093575b508160011b916000199060031b1c1916176009555b85600a5583600b558451600160401b8111612fc157600c5481600c55808210614001575b508890600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7916000905b828210613f215750505050613e8e926103156101009a9b93610307610323948b600d556040519d8e818152019061301b565b92608087015260a086015284820360c086015251808252602082019160208260051b82010194926000915b838310613ef45750505050509180917f62d6efdb8dbca656ac38d327c1d66a4ccaeabc91c464fe5e7352b604858f5f469360e08301520390a1565b9091929395602080613f12600193601f198682030187528a5161301b565b98019301930191939290613eb9565b80518051906001600160401b038211612fc157613f4882613f428854612c9c565b886133d6565b602090601f8311600114613f94579282600194936020938695600092613f89575b5050600019600383901b1c191690841b1787555b01940191019092613e5c565b015190503880613f69565b90601f198316918760005260206000209260005b818110613fe9575092600195928592879660209610613fd0575b505050831b83018755613f7d565b015160001960f88460031b161c19169055388080613fc2565b92936020600181928786015181550195019301613fa8565b600c6000527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7908282015b818301811061403c575050613e2e565b8061404960019254612c9c565b80614056575b500161402c565b601f8111831461406c5750600081555b3861404f565b60009082825261408a601f60208420920160051c82018583016133bf565b81835555614066565b90508b015138613df5565b600960009081527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9250601f198416908e5b82821061410c57505090836001949392106140f3575b5050811b01600955613e0a565b8d015160001960f88460031b161c1916905538806140e6565b600184956020939584930151815501940192018e6140d0565b61416e9060096000527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af601f840160051c8101916020851061341357601f0160051c01906133bf565b38613dde565b905084015138613da5565b600860009081527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39250601f198416905b8181106141eb575090836001949392106141d2575b5050811b01600855613dba565b86015160001960f88460031b161c1916905538806141c5565b9192602060018192868b0151815501940192016141b0565b61424c9060086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3601f840160051c8101916020851061341357601f0160051c01906133bf565b38613d8e565b905083015138613d55565b600760009081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889250601f198416905b8181106142c9575090836001949392106142b0575b5050811b01600755613d6a565b85015160001960f88460031b161c1916905538806142a3565b9192602060018192868a01518155019401920161428e565b61432a9060076000527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688601f840160051c8101916020851061341357601f0160051c01906133bf565b38613d3e565b905082015138613d05565b600660009081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f9250601f198416905b8181106143a75750908360019493921061438e575b5050811b01600655613d1a565b84015160001960f88460031b161c191690553880614381565b9192602060018192868901518155019401920161436c565b6144089060066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f601f840160051c8101916020851061341357601f0160051c01906133bf565b38613cee565b60405162461bcd60e51b815260206004820152600b60248201526a0496e76616c6964204b50560ac1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964204f4b544d4f60981b6044820152606490fd5b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b210353ab934b9b234b1ba34b7b760611b6044820152606490fd5b60405162461bcd60e51b815260206004820152601860248201527f4c6f636174696f6e2063616e6e6f7420626520656d70747900000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527553796d626f6c2063616e6e6f7420626520656d70747960501b6044820152606490fd5b60405162461bcd60e51b81526020600482015260146024820152734e616d652063616e6e6f7420626520656d70747960601b6044820152606490fd5b8251906001600160401b038211610352576020809161459b60409485848b0191888d010101613955565b8152019301929050613c87565b63f0f9e6b760e01b810361465f5750602081805181010312610352576020015180151580614654575b1561460f5760407fd0198ea88bf9c4ad5317b68e697944e524541fcb494d854f095b1cd88a097ab691601054908060105582519182526020820152a1565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642071756f72756d2070657263656e74616765000000000000006044820152606490fd5b5060648111156145d1565b632ab43f7f60e11b810361470f5750602081805181010312610352576020015180600052601660205261469960ff6040600020541661332c565b601254908181146146da577f979103c7afbf0138fe781172504ceb318ff78f9a420de8cabac8141f0121b521918160409260125582519182526020820152a1565b60405162461bcd60e51b815260206004820152600d60248201526c14d85b594818da185a5b881251609a1b6044820152606490fd5b6304fa45bf60e31b81036147dd57506040818051810103126103525760208101517ff14475b19484bf096265507cc0c41cd3bf1994992088806830686e2d72722719916001600160a01b039061476790604001613941565b16906147748215156148a3565b80600052601460205261478f60ff60406000205416156148de565b600081815260136020908152604080832080546001600160a01b031916861790556014825291829020805460ff1916600117905581519283526001600160a01b0390931692820192909252a1565b633972e9fb60e21b0361486a57602081805181010312610352576020807f4c7c76abe482a2c36ea52f1b999474c69f8b4afeeac5635f8aea2526864ba853920151806000526014825261483760ff60406000205416614922565b600081815260138352604080822080546001600160a01b03191690556014845290819020805460ff1916905551908152a1565b60405162461bcd60e51b81526020600482015260116024820152702ab735b737bbb71037b832b930ba34b7b760791b6044820152606490fd5b156148aa57565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b156148e557565b60405162461bcd60e51b81526020600482015260156024820152744d6f64756c6520616c72656164792065786973747360581b6044820152606490fd5b1561492957565b60405162461bcd60e51b8152602060048201526015602482015274135bd91d5b1948191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606490fd5b1561496d57565b60405162461bcd60e51b815260206004820152601760248201527f444c4520616c72656164792064656163746976617465640000000000000000006044820152606490fd5b156149b957565b60405162461bcd60e51b8152602060048201526024808201527f446561637469766174696f6e2070726f706f73616c20646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608490fd5b9081600052601b6020526137ad6040600020928354146149b256fe42e60114b8bc5803b43a4bcd35572ece9a5e2cabb79a838a02d56a4c53e833137585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd63a2646970667358221220c6e394d53611307294b6f8aac07316f9cb25a290fe9ad141368264da25827d2064736f6c63430008140033", + "bytecode": "0x6101608060405234620001f857620080518038038091620000208262000213565b833980820160408212620001f85782516001600160401b0392838211620001f85781906101809182910312620001f8576200005a6200027f565b9082860151858111620001f85784876200007792860101620002f7565b825280830151858111620001f85784876200009592860101620002f7565b60208301526101a0830151858111620001f8578487620000b892860101620002f7565b60408301526101c0830151858111620001f8578487620000db92860101620002f7565b60608301526101e0830151608083015261020083015160a0830152610220830151858111620001f857848762000114928601016200036a565b60c083015261024083015160e0830152610260830151956101009687840152610280840151868111620001f85785826200015192870101620003f5565b9561012096878501526102a0850151818111620001f857868362000178928801016200046c565b9561014096878601526102c0860151918211620001f85782620001a292620001ae9701016200046c565b90830152519062001209565b60405191615f6f938462002082853960805184612ee0015260a05184612f9b015260c05184612eaa015260e05184612f2f01525183612f55015251826118bc015251816118e80152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b601f01601f1916610160908101906001600160401b038211908210176200023957604052565b620001fd565b604081019081106001600160401b038211176200023957604052565b601f909101601f19168101906001600160401b038211908210176200023957604052565b6040519061018082016001600160401b038111838210176200023957604052565b6040519061014082016001600160401b038111838210176200023957604052565b60405190620002d0826200023f565b565b60005b838110620002e65750506000910152565b8181015183820152602001620002d5565b81601f82011215620001f85780516001600160401b0381116200023957604051926200032e601f8301601f1916602001856200025b565b81845260208284010111620001f8576200034f9160208085019101620002d2565b90565b6001600160401b038111620002395760051b60200190565b9080601f83011215620001f857815190620003858262000352565b926200039560405194856200025b565b828452602092838086019160051b83010192808411620001f857848301915b848310620003c55750505050505090565b82516001600160401b038111620001f8578691620003e984848094890101620002f7565b815201920191620003b4565b81601f82011215620001f8578051916200040f8362000352565b926200041f60405194856200025b565b808452602092838086019260051b820101928311620001f8578301905b8282106200044b575050505090565b81516001600160a01b0381168103620001f85781529083019083016200043c565b81601f82011215620001f857805191620004868362000352565b926200049660405194856200025b565b808452602092838086019260051b820101928311620001f8578301905b828210620004c2575050505090565b81518152908301908301620004b3565b90600182811c9216801562000504575b6020831014620004ee57565b634e487b7160e01b600052602260045260246000fd5b91607f1691620004e2565b8181106200051b575050565b600081556001016200050f565b90601f821162000536575050565b620002d09160036000526020600020906020601f840160051c8301931062000567575b601f0160051c01906200050f565b909150819062000559565b90601f821162000580575050565b620002d09160046000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f8211620005be575050565b620002d09160056000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f8211620005fc575050565b620002d09160066000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f82116200063a575050565b620002d091600d6000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f821162000678575050565b620002d091600e6000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f8211620006b6575050565b620002d091600f6000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b90601f8211620006f4575050565b620002d091600c6000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b9190601f81116200073457505050565b620002d0926000526020600020906020601f840160051c830193106200056757601f0160051c01906200050f565b80519091906001600160401b03811162000239576200078e8162000788600454620004d2565b62000572565b602080601f8311600114620007cd5750819293600092620007c1575b50508160011b916000199060031b1c191617600455565b015190503880620007aa565b6004600052601f198316949091907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b926000905b8782106200083c57505083600195961062000822575b505050811b01600455565b015160001960f88460031b161c1916905538808062000817565b8060018596829496860151815501950193019062000801565b80519091906001600160401b038111620002395762000881816200087b600d54620004d2565b6200062c565b602080601f8311600114620008c05750819293600092620008b4575b50508160011b916000199060031b1c191617600d55565b0151905038806200089d565b600d600052601f198316949091907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5926000905b8782106200092f57505083600195961062000915575b505050811b01600d55565b015160001960f88460031b161c191690553880806200090a565b80600185968294968601518155019501930190620008f4565b80519091906001600160401b038111620002395762000974816200096e600e54620004d2565b6200066a565b602080601f8311600114620009b35750819293600092620009a7575b50508160011b916000199060031b1c191617600e55565b01519050388062000990565b600e600052601f198316949091907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd926000905b87821062000a2257505083600195961062000a08575b505050811b01600e55565b015160001960f88460031b161c19169055388080620009fd565b80600185968294968601518155019501930190620009e7565b80519091906001600160401b038111620002395762000a678162000a61600f54620004d2565b620006a8565b602080601f831160011462000aa6575081929360009262000a9a575b50508160011b916000199060031b1c191617600f55565b01519050388062000a83565b600f600052601f198316949091907f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802926000905b87821062000b1557505083600195961062000afb575b505050811b01600f55565b015160001960f88460031b161c1916905538808062000af0565b8060018596829496860151815501950193019062000ada565b81519192916001600160401b038111620002395762000b5a8162000b538454620004d2565b8462000724565b602080601f831160011462000b9957508192939460009262000b8d575b50508160011b916000199060031b1c1916179055565b01519050388062000b77565b90601f1983169562000bb085600052602060002090565b926000905b88821062000bf05750508360019596971062000bd6575b505050811b019055565b015160001960f88460031b161c1916905538808062000bcc565b8060018596829496860151815501950193019062000bb5565b634e487b7160e01b600052601160045260246000fd5b80519068010000000000000000821162000239576012548260125580831062000c91575b50601260005260209081019060008051602062007ff18339815191526000925b84841062000c72575050505050565b6001838262000c848394518662000b2e565b0192019301929062000c63565b6012600090815260008051602062007ff18339815191529182019184015b82811062000cbf57505062000c43565b8062000cce60019254620004d2565b8062000cdd575b500162000caf565b601f90818111841462000cf75750508281555b3862000cd5565b8362000d1c9262000d0d85600052602060002090565b920160051c820191016200050f565b6000818152602081208183555562000cf0565b805180516001600160401b038111620002395762000d5a8162000d54600c54620004d2565b620006e6565b6020918290601f831160011462000e1b5762000dfd938361012094620002d0979462000da89460009262000e0f575b50508160011b916000199060031b1c191617600c555b82015162000855565b62000db7604082015162000948565b62000dc6606082015162000a3b565b608081015160105560a081015160115562000de560c082015162000c1f565b60e08101516013556101008101516014550151151590565b60ff8019601554169115151617601555565b01519050388062000d89565b600c600052601f19831691907fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c79260005b81811062000e9e575084620002d0979462000da89462000dfd9894610120986001951062000e84575b505050811b01600c5562000d9f565b015160001960f88460031b161c1916905538808062000e75565b92938660018192878601518155019501930162000e4c565b600019811462000ec65760010190565b62000c09565b634e487b7160e01b600052603260045260246000fd5b805182101562000ef75760209160051b010190565b62000ecc565b601e546801000000000000000081101562000239576001810180601e5581101562000ef757601e6000527f50bb669a95c7b50b7e8a6f09454034b2b14cf2b85c730dca9a539ca82cb6e3500155565b1562000f5457565b60405162461bcd60e51b815260206004820152601660248201527f417272617973206c656e677468206d69736d61746368000000000000000000006044820152606490fd5b1562000fa157565b60405162461bcd60e51b815260206004820152601360248201527f4e6f20696e697469616c20706172746e657273000000000000000000000000006044820152606490fd5b1562000fee57565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b156200102a57565b60405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b6044820152606490fd5b90815180825260208080930193019160005b8281106200107e575050505090565b8351855293810193928101926001016200106f565b9092916040820191604081528451809352606081019260208096019060005b818110620010cf575050506200034f93948184039101526200105d565b82516001600160a01b031686529487019491870191600101620010b2565b906020916200110881518092818552858086019101620002d2565b601f01601f1916010190565b96989a999795926200115d906200114e6200113e6200116c959794610140808d528c0190620010ed565b6020978b8203898d0152620010ed565b9089820360408b0152620010ed565b908782036060890152620010ed565b92608086015260a085015283820360c08501528551908183528083019281808460051b8301019801936000915b848310620011d8575050505050506200034f9495620011c99160e084015261010083019060018060a01b03169052565b6101208184039101526200105d565b9091929394988480620011f8600193601f198682030187528d51620010ed565b9b0193019301919493929062001199565b80519260208201938451816200121f926200146f565b81519284519260408101928351936060830190815194608085019889519660a087019788519060c08901519260e08a019b8c51956200125d620002a0565b9e8f91825260208201526040015260608d015260808c015260a08b015260c08a015260e089015261010042818a0152610120988981016200129e9060019052565b620012a99062000d2f565b85015160165560185560005b61016085018051805183101562001321576200130e83809362001307620012fa620012e96200131b98620013159762000ee2565b51600052601d602052604060002090565b805460ff19166001179055565b5162000ee2565b5162000efd565b62000eb6565b620012b5565b505050929597909396919497860195865151986200134861014083019a8b51511462000f4c565b62001357885151151562000f99565b60005b88518051821015620013d65790620013158c620013c96200139e84620013966200138982620013d09962000ee2565b516001600160a01b031690565b935162000ee2565b51620013b56001600160a01b038416151562000fe6565b620013c281151562001022565b82620015e2565b8062001f92565b6200135a565b5050909192939598977ff9e7aa11bcdcbb8ac33b5dba92fca799ef091e54c29270822065501d8edea1a57f11b248463a1620b36a975da8f250009f56fb5dd0e9d5027a90a834d0ee84d6f6996200146a9799519051906200143d6040519283928362001093565b0390a18251935196519751945190519061016060c0850151935194015195604051998a9930978b62001114565b0390a1565b929190926040519062001482826200023f565b60019283835260209081840194603160f81b865287519060018060401b0382116200023957620014bf82620014b9600354620004d2565b62000528565b8398601f831160011462001555578291620014fc95969798999a839260009462001549575b50501b916000199060031b1c19161760035562000762565b6200150782620016b0565b610120526200151683620017c0565b61014052815191012060e052519020610100524660a0526200153762001925565b6080523060c052620002d06001600b55565b015192503880620014e4565b6003600052601f198316999192917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9160005b8c8110620015cc575083620014fc9798999a9b9c10620015b2575b505050811b0160035562000762565b015160001960f88460031b161c19169055388080620015a3565b8183015184559285019291870191870162001588565b91906001600160a01b0383168015620016975760025482810180911162000ec6576002556001600160a01b038416600090815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a3600254926001600160d01b0384116200166d57620002d092935062001991565b604051630e58ae9360e11b8152600481018590526001600160d01b036024820152604490fd5b0390fd5b60405163ec442f0560e01b815260006004820152602490fd5b9081516020808210600014620016ce575050906200034f90620018d0565b6001600160401b0382116200023957620016f582620016ef600554620004d2565b620005b0565b80601f831160011462001735575081929360009262001729575b50508160011b916000199060031b1c19161760055560ff90565b0151905038806200170f565b6005600052601f198316949091907f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0926000905b878210620017a75750508360019596106200178d575b505050811b0160055560ff90565b015160001960f88460031b161c191690553880806200177f565b8060018596829496860151815501950193019062001769565b9081516020808210600014620017de575050906200034f90620018d0565b6001600160401b03821162000239576200180582620017ff600654620004d2565b620005ee565b80601f831160011462001845575081929360009262001839575b50508160011b916000199060031b1c19161760065560ff90565b0151905038806200181f565b6006600052601f198316949091907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f926000905b878210620018b75750508360019596106200189d575b505050811b0160065560ff90565b015160001960f88460031b161c191690553880806200188f565b8060018596829496860151815501950193019062001879565b601f815111620018fe576020815191015160208210620018ee571790565b6000198260200360031b1b161790565b60405163305a27a960e01b81526020600482015290819062001693906024830190620010ed565b60e051610100516040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815260c0810181811060018060401b03821117620002395760405251902090565b906200199d8162001ccd565b9165ffffffffffff80431162001a7b57600a5460008162001a48575050620019d990620019d0620002d09560006200204d565b90431662001dc9565b50506001600160a01b0390811690811562001a2b575b60086020527f5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c75460009283526040909220548116911662001a9a565b62001a4062001a3a8462001ccd565b62001c18565b5050620019ef565b60009291921995838781011162000ec657620002d096620019d994602084600a620019d096522001015460301c6200204d565b6040516306dfcc6560e41b815260306004820152436024820152604490fd5b6001600160a01b0380831693929190811690818514158062001c0e575b62001ac4575b5050505050565b8162001b40575b50508262001adc575b808062001abd565b6001600160a01b03166000908152600960205260409020600080516020620080318339815191529162001b1c9162001b15909162001ccd565b9062001c75565b604080516001600160d01b039384168152919092166020820152a238808062001ad4565b6001600160a01b0316600090815260096020526040902062001b628462001ccd565b9065ffffffffffff9081431162001a7b57805460008162001bcf5750509062001bac9162001ba26000805160206200803183398151915294600062002067565b9143169062001ec5565b604080516001600160d01b039384168152919092166020820152a2388062001acb565b6000939291931994848681011162000ec657600080516020620080318339815191529562001bac956020848662001ba296522001015460301c62002067565b5083151562001ab7565b65ffffffffffff80431162001a7b57600a5460008162001c49575050620019d062001c4592600062002067565b9091565b9092600019848181011162000ec65762001c4594602084600a620019d096522001015460301c62002067565b65ffffffffffff9081431162001a7b57805460008162001ca257505062001ba262001c459360006200204d565b9093600019858181011162000ec65762001c45956020848662001ba296522001015460301c6200204d565b6001600160d01b039081811162001ce2571690565b604490604051906306dfcc6560e41b825260d060048301526024820152fd5b60001981019190821162000ec657565b600a54906801000000000000000082101562000239576001820180600a5582101562000ef757600a60005280516020919091015160301b65ffffffffffff191665ffffffffffff91909116176000805160206200801183398151915290910155565b9081546801000000000000000081101562000239576001810180845581101562000ef75760009283526020928390208251929093015160301b65ffffffffffff191665ffffffffffff9290921691909117910155565b600a54919291801562001e965762001de562001dfe9162001d01565b600a600052600080516020620080118339815191520190565b9081549165ffffffffffff9081841691831680831162001e845786920362001e465762001e3f92509065ffffffffffff82549181199060301b169116179055565b60301c9190565b505062001e7e9062001e6962001e5b620002c1565b65ffffffffffff9092168252565b6001600160d01b038516602082015262001d11565b62001e3f565b604051632520601d60e01b8152600490fd5b5062001ebf9062001eaa62001e5b620002c1565b6001600160d01b038416602082015262001d11565b60009190565b8054929392801562001f685762001ee062001eed9162001d01565b8260005260206000200190565b9182549265ffffffffffff9182851692811680841162001e845787930362001f2f575062001e3f92509065ffffffffffff82549181199060301b169116179055565b91505062001e7e9162001f5362001f45620002c1565b65ffffffffffff9093168352565b6001600160d01b038616602083015262001d73565b509062001ebf9162001f7d62001f45620002c1565b6001600160d01b038516602083015262001d73565b6001600160a01b039081169180821691828403620020085760008481526008602052604080822080546001600160a01b031981168717909155620002d096931694909285907f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f8480a48060205220549162001a9a565b60405162461bcd60e51b815260206004820152601360248201527f44656c65676174696f6e2064697361626c6564000000000000000000000000006044820152606490fd5b6001600160d01b039182169082160190811162000ec65790565b6001600160d01b039182169082160390811162000ec6579056fe6080604052600436101561001257600080fd5b60003560e01c8063013cf08b146103de57806306fdde03146103d9578063078f6208146103d4578063095ea7b3146103cf5780630c0512e9146103ca5780630d61b519146103c557806318160ddd146103c0578063204c5d1f146103bb57806322dbefbb1461030c57806322f3e2d4146103b657806323b872dd146103b15780632519ae5c146103ac578063313ce567146103a75780633644e515146103a25780633a46b1a8146102d557806347c661401461039d5780634b145793146103075780634bf5d7e9146103985780634cf2ab32146103935780634cfd16bb1461038e5780634de184f6146103845780634fa76ec9146103895780635221c1f014610384578063548d496f1461037f578063587cde1e1461037a5780635c19a95c146103755780635cf0e8a4146103705780636cbadbfa146103705780636dcf811d1461036b5780636fcfff451461036657806370a08231146103615780637ce288ea1461035c5780637e5a9b47146103575780637ecebe00146103525780637f6dda141461034d57806384b0196e1461034857806385e59ce2146103435780638e539e8c1461033e5780639080936f1461033957806391ddadf41461033457806395d89b411461032f57806398e527d31461032a5780639a49bdde146103255780639ab24eb014610320578063a351f6151461031b578063a9059cbb14610316578063adf7420714610311578063b0b6cc1a1461030c578063b3fe8bcb14610307578063c3cda52014610302578063c8a6d06e146102fd578063c97bfe6b146102f8578063c9a3c0c7146102f3578063c9d27afe146102ee578063d505accf146102e9578063dcf628c0146102e4578063dd62ed3e146102df578063e49a62e9146102da578063eaeded5f146102d5578063eced3dfb146102d0578063f1127ed8146102cb5763f2c26a47146102c657600080fd5b6128bb565b612795565b612777565b6112d6565b612759565b6126f6565b612659565b6124a8565b61235b565b612226565b6121d5565b612139565b611ff7565b611397565b610f45565b611ce7565b611c8d565b611b4f565b611b06565b611ae8565b611aca565b611a23565b6119f7565b6119ce565b61199c565b611965565b6118a3565b61186d565b611830565b611802565b611777565b61173a565b6116cd565b6116aa565b61168c565b611664565b611625565b6115f4565b61159f565b6115d6565b611525565b6114b2565b6113c8565b611301565b6112b3565b611297565b6110ec565b610fb0565b610f79565b610e62565b610d32565b610c26565b610c08565b610bd3565b610b93565b610ab2565b6109f5565b90600182811c92168015610413575b60208310146103fd57565b634e487b7160e01b600052602260045260246000fd5b91607f16916103f2565b600d546000929161042d826103e3565b80825291600190818116908115610492575060011461044b57505050565b91929350600d600052600080516020615eda833981519152916000925b84841061047a57505060209250010190565b80546020858501810191909152909301928101610468565b915050602093945060ff929192191683830152151560051b010190565b600e54600092916104bf826103e3565b8082529160019081811690811561049257506001146104dd57505050565b91929350600e600052600080516020615e9a833981519152916000925b84841061050c57505060209250010190565b805460208585018101919091529093019281016104fa565b600f5460009291610534826103e3565b80825291600190818116908115610492575060011461055257505050565b91929350600f600052600080516020615f1a833981519152916000925b84841061058157505060209250010190565b8054602085850181019190915290930192810161056f565b90600092918054916105aa836103e3565b91828252600193848116908160001461060c57506001146105cc575b50505050565b90919394506000526020928360002092846000945b8386106105f85750505050010190388080806105c6565b8054858701830152940193859082016105e1565b9294505050602093945060ff191683830152151560051b010190388080806105c6565b634e487b7160e01b600052604160045260246000fd5b61014081019081106001600160401b0382111761066157604052565b61062f565b604081019081106001600160401b0382111761066157604052565b60a081019081106001600160401b0382111761066157604052565b60c081019081106001600160401b0382111761066157604052565b90601f801991011681019081106001600160401b0382111761066157604052565b60405190600082600c54916106ec836103e3565b808352926001908181169081156107625750600114610715575b50610713925003836106b7565b565b600c60009081529150600080516020615e7a8339815191525b8483106107475750610713935050810160200138610706565b81935090816020925483858a0101520191019091859261072e565b90506020925061071394915060ff191682840152151560051b82010138610706565b60405190600082600d5491610798836103e3565b8083529260019081811690811561076257506001146107be5750610713925003836106b7565b600d60009081529150600080516020615eda8339815191525b8483106107f05750610713935050810160200138610706565b81935090816020925483858a010152019101909185926107d7565b60405190600082600e549161081f836103e3565b8083529260019081811690811561076257506001146108455750610713925003836106b7565b600e60009081529150600080516020615e9a8339815191525b8483106108775750610713935050810160200138610706565b81935090816020925483858a0101520191019091859261085e565b60405190600082600f54916108a6836103e3565b8083529260019081811690811561076257506001146108cc5750610713925003836106b7565b600f60009081529150600080516020615f1a8339815191525b8483106108fe5750610713935050810160200138610706565b81935090816020925483858a010152019101909185926108e5565b9061071361092d9260405193848092610599565b03836106b7565b60005b8381106109475750506000910152565b8181015183820152602001610937565b9060209161097081518092818552858086019101610934565b601f01601f1916010190565b989490936109a86109e4989497936101609c9f9e9d9a968c5260208c61018091829101528c0190610957565b60408b019790975260608a015215156080890152151560a088015260c08701526001600160a01b031660e0860152848203610100860152610957565b956101208301526101408201520152565b34610a99576020366003190112610a9957600435600052601b60205260406000208054610a9560405191610a3783610a308160018801610599565b03846106b7565b600284015460038501546004860154600587015460068801549397929492936001600160a01b031690610a6c60078601610919565b92600886015494600b600a880154970154976040519b8c9b60ff808660081c169516938d61097c565b0390f35b600080fd5b906020610aaf928181520190610957565b90565b34610a9957600080600319360112610b90576040519080600354610ad5816103e3565b80855291600191808316908115610b665750600114610b0b575b610a9585610aff818703826106b7565b60405191829182610a9e565b9250600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610b4e575050508101602001610aff82610a95610aef565b80546020858701810191909152909301928101610b33565b869550610a9596935060209250610aff94915060ff191682840152151560051b8201019293610aef565b80fd5b34610a99576000366003190112610a99576060601654601854601e549060405192835260208301526040820152f35b6001600160a01b03811603610a9957565b34610a99576040366003190112610a9957610bfd600435610bf381610bc2565b6024359033612bf5565b602060405160018152f35b34610a99576000366003190112610a99576020601754604051908152f35b34610a99576020366003190112610a99577fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d26004356007610c7182600052601b602052604060002090565b610c7d8382541461402d565b610cfc60048201610c9e610c99610c95835460ff1690565b1590565b6140b4565b610caf60185460088501541461423b565b610cdf610cbb866141cd565b60058601544210801590610d2b575b610cd390614286565b81610d23575b506142e2565b610cef600a840154421015614324565b805460ff19166001179055565b0190610d0f610d0a83610919565b614aa7565b610d1e60405192839283614367565b0390a1005b905038610cd9565b5080610cca565b34610a99576000366003190112610a99576020600254604051908152f35b90815180825260208092019182818360051b85019501936000915b848310610d7b5750505050505090565b9091929394958480610d9583856001950387528a51610957565b9801930193019194939290610d6b565b610aaf90602081528251610e3d610dca61014092836020860152610160850190610957565b610e14610e00610dec602089015193601f1994858983030160408a0152610957565b604089015184888303016060890152610957565b606088015183878303016080880152610957565b90608087015160a086015260a087015160c086015260c0870151908583030160e0860152610d50565b9360e08101516101009081850152810151906101209182850152015191019015159052565b34610a9957600080600319360112610b9057610a9590610f39604051610e8781610645565b60609283825283602083015283604083015283808301528060808301528060a08301528360c08301528060e083015261010090808284015261012080930152610ece611065565b93610ed76106d8565b8552610ee1610784565b6020860152610eee61080b565b6040860152610efb610892565b90850152601054608085015260115460a0850152610f17615621565b60c085015260135460e08501526014549084015260155460ff16151590830152565b60405191829182610da5565b34610a99576020366003190112610a99576004356000526019602052602060018060a01b0360406000205416604051908152f35b34610a99576000366003190112610a995760ff601f54161580610fa4575b6020906040519015158152f35b5060155460ff16610f97565b34610a99576060366003190112610a9957600435610fcd81610bc2565b602435610fd981610bc2565b6001600160a01b03821660009081526001602090815260408083203384529091529020604435919054926000198410611023575b6110179350612ae3565b60405160018152602090f35b82841061103f5761103a8361101795033383612ca9565b61100d565b604051637dc7a0d960e11b81523360048201526024810185905260448101849052606490fd5b6040519061071382610645565b6040519061071382610666565b6001600160401b03811161066157601f01601f191660200190565b9291926110a68261107f565b916110b460405193846106b7565b829481845281830111610a99578281602093846000960137010152565b9080601f83011215610a9957816020610aaf9335910161109a565b34610a995760a0366003190112610a99576004356001600160401b038111610a995761111f610a959136906004016110d1565b7f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd636112846044359261127660643561115681610bc2565b61117e611179611172608435600052601d602052604060002090565b5460ff1690565b613629565b6111926001600160a01b038216151561543e565b6111b46111af610c9561117289600052601a602052604060002090565b615479565b3360009081526020819052604090206111d0905b541515613585565b6007601754966111e76111e2896136aa565b601755565b6112706111fe89600052601b602052604060002090565b9189835561120f8760018501613b81565b61121b60243542613250565b60058401556006830180546001600160a01b031916331790556040516304fa45bf60e31b602082015260248101919091526001600160a01b03909416604485015283606481015b03601f1981018552846106b7565b01613b81565b604051918291338684613d69565b0390a16040519081529081906020820190565b34610a99576000366003190112610a9957602060405160128152f35b34610a99576000366003190112610a995760206112ce612ea7565b604051908152f35b34610a99576040366003190112610a995760206112ce6004356112f881610bc2565b602435906129d2565b34610a99576020366003190112610a995760043580600052601b60205261132f60406000209182541461402d565b606461135a60018060d01b0361135061134b600b860154612a8c565b61325d565b16601654906141ba565b049060036002820154910154918282019081831161139257604080519384526020840194909452928201526060810191909152608090f35b612acd565b34610a99576020366003190112610a9957600435600052601a602052602060ff604060002054166040519015158152f35b34610a99576000366003190112610a99576113e2436131f4565b65ffffffffffff806113f3436131f4565b1691160361144857610a9560405161140a81610666565b601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c740000006020820152604051918291602083526020830190610957565b6040516301bfc1c560e61b8152600490fd5b634e487b7160e01b600052603260045260246000fd5b601e5481101561149557601e600052600080516020615efa8339815191520190600090565b61145a565b80548210156114955760005260206000200190600090565b34610a99576020366003190112610a9957600435601e54811015610a9957602090601e600052600080516020615efa8339815191520154604051908152f35b90815180825260208080930193019160005b828110611511575050505090565b835185529381019392810192600101611503565b34610a99576000366003190112610a995760405180601e54808252826020809301601e600052600080516020615efa8339815191529260005b8582821061158957505050611575925003836106b7565b610a956040519282849384528301906114f1565b855484526001958601958895509301920161155e565b34610a99576020366003190112610a995760206115cc600435600052601d60205260ff6040600020541690565b6040519015158152f35b34610a99576000366003190112610a99576020601654604051908152f35b34610a99576020366003190112610a9957600435600052601d602052602060ff604060002054166040519015158152f35b34610a99576020366003190112610a9957602060043561164481610bc2565b60018060a01b038091166000526008825260406000205416604051908152f35b34610a99576020366003190112610a995761168a60043561168481610bc2565b33615da9565b005b34610a99576000366003190112610a99576020601854604051908152f35b34610a99576000366003190112610a9957602060ff601f54166040519015158152f35b34610a99576020366003190112610a99576004356116ea81610bc2565b6001600160a01b031660009081526009602052604090205463ffffffff9081811161171b5760209160405191168152f35b604490604051906306dfcc6560e41b8252602060048301526024820152fd5b34610a99576020366003190112610a995760206112ce60043561175c81610bc2565b6001600160a01b031660009081526020819052604090205490565b34610a99576020366003190112610a9957600435611794816147f4565b156117c65760207f57df5a6a467271f04b10f7fe9e66d21dcd8ae7eaf079099d48959f24a53b691091604051908152a1005b60405162461bcd60e51b81526020600482015260146024820152734e6f7420616c6c20636861696e7320726561647960601b6044820152606490fd5b34610a99576020366003190112610a995760406118206004356141cd565b8251911515825215156020820152f35b34610a99576020366003190112610a995760043561184d81610bc2565b60018060a01b031660005260076020526020604060002054604051908152f35b34610a99576040366003190112610a9957610a9561188f6024356004356156f3565b6040519182916020835260208301906114f1565b34610a99576000366003190112610a99576119366118e07f0000000000000000000000000000000000000000000000000000000000000000613041565b610a9561190c7f000000000000000000000000000000000000000000000000000000000000000061313a565b611944611917612fe7565b91604051958695600f60f81b875260e0602088015260e0870190610957565b908582036040870152610957565b90466060850152306080850152600060a085015283820360c08501526114f1565b34610a99576020366003190112610a9957602060646119936001600160d01b0361135061134b600435612a8c565b04604051908152f35b34610a99576020366003190112610a995760206001600160d01b036119c561134b600435612a8c565b16604051908152f35b34610a99576020366003190112610a995760206119ec60043561579e565b60ff60405191168152f35b34610a99576000366003190112610a99576020611a13436131f4565b65ffffffffffff60405191168152f35b34610a9957600080600319360112610b90576040519080600454611a46816103e3565b80855291600191808316908115610b665750600114611a6f57610a9585610aff818703826106b7565b9250600483527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410611ab2575050508101602001610aff82610a95610aef565b80546020858701810191909152909301928101611a97565b34610a99576000366003190112610a99576020601c54604051908152f35b34610a99576020366003190112610a995760206112ce60043561485b565b34610a99576020366003190112610a9957600435611b2381610bc2565b6001600160a01b031660009081526009602090815260409091206001600160d01b03906119c5906134f6565b34610a99576040366003190112610a99576004356001600160401b03602435818111610a995736602382011215610a99578060040135918211610a99573660248383010111610a9957610d1e60249284611c7f611bd77fc7c129e53e59dadfa16305619e80c7519f1f6912c10915359fd75b56bcecdd7b97600052601b602052604060002090565b611be38382541461402d565b611c70600b6004830192611c03611bfe60ff86541615151590565b614409565b611c1260058201544210614079565b6006810154611c3c90611c35906001600160a01b03165b6001600160a01b031690565b3314614448565b0154611c69611c4b82336129d2565b916001600160d01b0390611c629061134b90612a8c565b16916141a4565b1015614485565b805461ff001916610100179055565b6040519485940190846144dd565b34610a99576040366003190112610a9957610bfd600435611cad81610bc2565b6024359033612ae3565b9181601f84011215610a99578235916001600160401b038311610a99576020808501948460051b010111610a9957565b34610a99576060366003190112610a99576001600160401b03600435602435828111610a9957611d1b903690600401611cb7565b92604435908111610a995783611d3684923690600401611cb7565b611d3e614181565b611d5284600052601b602052604060002090565b90611d5f8583541461402d565b6004820192611d7a611d75610c95865460ff1690565b61450b565b60185494611d8e6008850154871415614567565b611da0611d9b8786615876565b6145c3565b611db0600a850154421015614324565b611dbb838214614606565b611e45876007860197611e3d600b611dd28b610919565b6020815191012098015497611e2f896040519485936020850197889094939260809260a08301967f45de75acfcd4cbcc5691559486749bf0d5eb65e4b24c59ac2f258ba6bfceaa3484526020840152604083015260608201520152565b03601f1981018352826106b7565b519020612fc1565b9760009889945b838610611f0d575050507fda7dba8f94d70cde423cce3a243bebf95d2ec927507b566f67e329dcfe2d06bb877fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d2611ee689611ecd8a610cef8f611ec6611ebf8e61135061134b60018060d01b0392612a8c565b6064900490565b1115614765565b611ed9610d0a82610919565b6040519182918583614367565b0390a1601854604080519283526020830191909152819081015b0390a161168a6001600b55565b909192939499868b611f49611c29611f44611f3c611f36611f2f868a8f614643565b369161109a565b896147b1565b938a8a614684565b614694565b6001600160a01b03821690611f5f90821461469e565b8d88886000925b8310611fa2575050505091611f81611f9292611f98946129d2565b90611f8d821515614719565b613250565b9a6136aa565b9493929190611e4c565b8394955092611fbe611c29611f4485611fc595611fca98614684565b14156146da565b6136aa565b90899291888f8990611f66565b6064359060ff82168203610a9957565b6084359060ff82168203610a9957565b34610a995760c0366003190112610a995760043561201481610bc2565b60443590602435612023611fd7565b8342116120ab5761209f61168a946120a6926040519060208201927fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf845260018060a01b038816604084015286606084015260808301526080825261208782610681565b61209a60a4359360843593519020612fc1565b612d52565b9182612cfc565b615da9565b604051632341d78760e11b815260048101859052602490fd5b6001600160401b0381116106615760051b60200190565b81601f82011215610a99578035916120f2836120c4565b9261210060405194856106b7565b808452602092838086019260051b820101928311610a99578301905b82821061212a575050505090565b8135815290830190830161211c565b34610a995760c0366003190112610a99576001600160401b03600435818111610a995761216a9036906004016110d1565b90604435818111610a995736602382011215610a995761219490369060248160040135910161109a565b608435918211610a9957610a95926121b36121c59336906004016120db565b9060a435926064359160243590613da8565b6040519081529081906020820190565b34610a99576020366003190112610a9957600435601c54811015610a9957602090601c6000527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110154604051908152f35b34610a99576080366003190112610a99576004356001600160401b038111610a9957612259610a959136906004016110d1565b7f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd636112846044359261229d611179611172606435600052601d602052604060002090565b6122bc6122b761117286600052601a602052604060002090565b6154bd565b3360009081526020819052604090206122d4906111c8565b6112766112626007601754966122ec6111e2896136aa565b61127061230389600052601b602052604060002090565b918983556123148760018501613b81565b61232060243542613250565b60058401556006830180546001600160a01b03191633179055604051633972e9fb60e21b602082015260248101919091529384906044820190565b34610a99576040366003190112610a99576004356024358015158103610a99577f78975aaf742630489badd22949b88ac50eaaea576339ee05440b671a33bfb6a9916123a5614181565b611f006123bc82600052601b602052604060002090565b6123c88382541461402d565b6123d760058201544210614079565b6123eb610c99610c95600484015460ff1690565b600c81019061241a612415610c9561117233869060018060a01b0316600052602052604060002090565b614100565b61242b60185460088301541461413c565b612453610cef61243f600b840154336129d2565b336000908152602095909552604090942090565b841561249357600201612467828254613250565b90555b604080519384523360208501529315159383019390935260608201929092529081906080820190565b6003016124a1828254613250565b905561246a565b34610a995760e0366003190112610a99576004356124c581610bc2565b6024356124d181610bc2565b604435906064356124e0611fe7565b8142116125cb576001600160a01b0385811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019283529283019390935292861660608201526080810187905260a081019190915260c08082019490945292835261258492909161257160e0836106b7565b61209a60c4359360a43593519020612fc1565b6001600160a01b03848116908216036125a1575061168a92612bf5565b6040516325c0072360e11b81526001600160a01b0391821660048201529084166024820152604490fd5b60405163313c898160e11b815260048101839052602490fd5b9895929a97949161260a90610aaf9d9b9895928b526101808060208d01528b0190610957565b60408a019b909b52606089015215156080880152151560a087015260c08601526001600160a01b031660e0850152610100840152610120830152610140820152808303610160909101526114f1565b34610a99576020366003190112610a995760043580600052601b6020526040600020612688815492831461402d565b610a95600282015492600383015490600484015460058501546126b4600687015460018060a01b031690565b600887015491600a88015493600b890154956126de60096126d760018d01610919565b9b016156a4565b976040519b8c9b60ff808660081c169516938d6125e4565b34610a99576040366003190112610a9957602061275060043561271881610bc2565b6024359061272582610bc2565b60018060a01b03166000526001835260406000209060018060a01b0316600052602052604060002090565b54604051908152f35b34610a99576020366003190112610a995760206115cc6004356147f4565b34610a99576000366003190112610a99576020601e54604051908152f35b34610a99576040366003190112610a99576004356127b281610bc2565b6024359063ffffffff82168203610a9957610a9591612802916127d3612ce3565b506127dc612ce3565b506001600160a01b031660009081526009602052604090206127fc612ce3565b5061149a565b506040519061281082610666565b5465ffffffffffff811680835260309190911c60209283019081526040805192835290516001600160d01b031692820192909252918291820190565b9794999895926128919061288361289f946128756101009b98958d610120908181520190610957565b8c810360208e015290610957565b908a820360408c0152610957565b9088820360608a0152610957565b97608087015260a086015260c085015260e08401521515910152565b34610a9957600080600319360112610b9057604051908181600c546128df816103e3565b808452936001918083169081156129ae5750600114612963575b5050612907925003826106b7565b604051906129188261092d8161041d565b610a956040516129328161292b816104af565b03826106b7565b6040516129428161292b81610524565b601054601154601354916014549360ff6015541695604051998a998a61284c565b9150600c8252600080516020615e7a8339815191525b8483106129935750612907935050810160200138806128f9565b81935090816020925483858901015201910190918492612979565b9150506020925061290794915060ff191682840152151560051b82010138806128f9565b6001600160a01b0316600090815260096020526040812090916129f490612a8c565b81549083829160058411612a3d575b612a0e935084613524565b80612a225750505b6001600160d01b031690565b91612a2f60209293613226565b92815220015460301c612a16565b9192612a4881613381565b810390811161139257612a0e9385875265ffffffffffff808360208a2001541690851610600014612a7a575091612a03565b929150612a8690613242565b90612a03565b65ffffffffffff612a9c436131f4565b1680821015612aaf5750610aaf906131f4565b6044925060405191637669fc0f60e11b835260048301526024820152fd5b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0380821694939291908515612bdc5782168015612bc3576001600160a01b03821660009081526020819052604090205495848710612b945784610713969703612b458460018060a01b03166000526000602052604060002090565b556001600160a01b0384166000908152602081815260409182902080548801905590518681527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a36158c1565b60405163391434e360e21b81526001600160a01b03841660048201526024810188905260448101869052606490fd5b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b6001600160a01b038082169291908315612c90578216938415612c775780612c6d7f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92594612c5660209560018060a01b03166000526001602052604060002090565b9060018060a01b0316600052602052604060002090565b55604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b906001600160a01b0380831615612c9057811615612c7757612c56612ce09260018060a01b03166000526001602052604060002090565b55565b60405190612cf082610666565b60006020838281520152565b6001600160a01b03811660009081526007602052604090208054600181019091559091819003612d2a575050565b6040516301d4b62360e61b81526001600160a01b039092166004830152602482015260449150fd5b91610aaf9391612d6193612d6a565b90929192612e1a565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411612dee57926020929160ff608095604051948552168484015260408301526060820152600092839182805260015afa15612de25780516001600160a01b03811615612dd957918190565b50809160019190565b604051903d90823e3d90fd5b50505060009160039190565b60041115612e0457565b634e487b7160e01b600052602160045260246000fd5b612e2381612dfa565b80612e2c575050565b612e3581612dfa565b60018103612e4f5760405163f645eedf60e01b8152600490fd5b612e5881612dfa565b60028103612e795760405163fce698f760e01b815260048101839052602490fd5b80612e85600392612dfa565b14612e8d5750565b6040516335e2f38360e21b81526004810191909152602490fd5b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480612f98575b15612f02577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a08152612f928161069c565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000004614612ed9565b604290612fcc612ea7565b906040519161190160f01b8352600283015260228201522090565b604051602081018181106001600160401b038211176106615760405260008152906000368137565b90613019826120c4565b61302660405191826106b7565b8281528092613037601f19916120c4565b0190602036910137565b60ff811461307f5760ff811690601f821161306d576040519161306383610666565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554816000613092836103e3565b8083529260019081811690811561311857506001146130b9575b50610aaf925003826106b7565b6005600090815291507f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8483106130fd5750610aaf9350508101602001386130ac565b819350908160209254838589010152019101909184926130e4565b905060209250610aaf94915060ff191682840152151560051b820101386130ac565b60ff811461315c5760ff811690601f821161306d576040519161306383610666565b5060405160065481600061316f836103e3565b8083529260019081811690811561311857506001146131955750610aaf925003826106b7565b6006600090815291507ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f5b8483106131d95750610aaf9350508101602001386130ac565b819350908160209254838589010152019101909184926131c0565b65ffffffffffff90818111613207571690565b604490604051906306dfcc6560e41b8252603060048301526024820152fd5b60001981019190821161139257565b9190820391821161139257565b906001820180921161139257565b9190820180921161139257565b600a80546000816005811161330b575b509290925b8381106132b1575050600091801560001461328f57505050600090565b61329890613226565b9152600080516020615eba833981519152015460301c90565b90928082169080831860011c8201809211611392578360005265ffffffffffff8083600080516020615eba833981519152015416908616106000146132f95750925b90613272565b93915061330590613242565b906132f3565b909161331682613381565b82039182116113925783835265ffffffffffff8083600080516020615eba833981519152015416908616106000146133515750905b3861326d565b915061335c90613242565b61334b565b811561336b570490565b634e487b7160e01b600052601260045260246000fd5b6001811115610aaf57600181600160801b81101561349a575b61344261343861342e61342461341a61341061344e97600488600160401b6134499a101561348d575b640100000000811015613480575b62010000811015613473575b610100811015613467575b601081101561345b575b1015613453575b60030260011c613409818b613361565b0160011c90565b613409818a613361565b6134098189613361565b6134098188613361565b6134098187613361565b6134098186613361565b8093613361565b821190565b900390565b60011b6133f9565b811c9160021b916133f2565b60081c91811b916133e8565b60101c9160081b916133dd565b60201c9160101b916133d1565b60401c9160201b916133c3565b50600160401b9050608082901c61339a565b600a54600090806134be575050600090565b8060001981011161139257600a7fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a79252015460301c90565b80546000918161350857505050600090565b6000199282848101116113925760209181522001015460301c90565b91905b8382106135345750505090565b9091928083169080841860011c82018092116113925760008581526020902082015465ffffffffffff90811690841610156135735750925b9190613527565b93925061357f90613242565b9161356c565b1561358c57565b60405162461bcd60e51b815260206004820152602360248201527f4d75737420686f6c6420746f6b656e7320746f206372656174652070726f706f6044820152621cd85b60ea1b6064820152608490fd5b156135e457565b60405162461bcd60e51b815260206004820152601960248201527f4475726174696f6e206d75737420626520706f736974697665000000000000006044820152606490fd5b1561363057565b60405162461bcd60e51b815260206004820152601360248201527210da185a5b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606490fd5b1561367257565b60405162461bcd60e51b815260206004820152601060248201526f54696d656c6f636b20746f6f2062696760801b6044820152606490fd5b60001981146113925760010190565b8181106136c4575050565b600081556001016136b9565b90601f82116136dd575050565b61071391600c600052600080516020615e7a833981519152906020601f840160051c83019310613715575b601f0160051c01906136b9565b9091508190613708565b90601f821161372c575050565b61071391600d600052600080516020615eda833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b90601f8211613770575050565b61071391600e600052600080516020615e9a833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b90601f82116137b4575050565b61071391600f600052600080516020615f1a833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b9190601f81116137fa57505050565b610713926000526020600020906020601f840160051c8301931061371557601f0160051c01906136b9565b9081516001600160401b0381116106615761384a81613845600c546103e3565b6136d0565b602080601f8311600114613886575081929360009261387b575b50508160011b916000199060031b1c191617600c55565b015190503880613864565b90601f198316946138a7600c600052600080516020615e7a83398151915290565b926000905b8782106138e45750508360019596106138cb575b505050811b01600c55565b015160001960f88460031b161c191690553880806138c0565b806001859682949686015181550195019301906138ac565b9081516001600160401b038111610661576139218161391c600d546103e3565b61371f565b602080601f831160011461395d5750819293600092613952575b50508160011b916000199060031b1c191617600d55565b01519050388061393b565b90601f1983169461397e600d600052600080516020615eda83398151915290565b926000905b8782106139bb5750508360019596106139a2575b505050811b01600d55565b015160001960f88460031b161c19169055388080613997565b80600185968294968601518155019501930190613983565b9081516001600160401b038111610661576139f8816139f3600e546103e3565b613763565b602080601f8311600114613a345750819293600092613a29575b50508160011b916000199060031b1c191617600e55565b015190503880613a12565b90601f19831694613a55600e600052600080516020615e9a83398151915290565b926000905b878210613a92575050836001959610613a79575b505050811b01600e55565b015160001960f88460031b161c19169055388080613a6e565b80600185968294968601518155019501930190613a5a565b9081516001600160401b03811161066157613acf81613aca600f546103e3565b6137a7565b602080601f8311600114613b0b5750819293600092613b00575b50508160011b916000199060031b1c191617600f55565b015190503880613ae9565b90601f19831694613b2c600f600052600080516020615f1a83398151915290565b926000905b878210613b69575050836001959610613b50575b505050811b01600f55565b015160001960f88460031b161c19169055388080613b45565b80600185968294968601518155019501930190613b31565b91909182516001600160401b03811161066157613ba881613ba284546103e3565b846137eb565b602080601f8311600114613be4575081929394600092613bd9575b50508160011b916000199060031b1c1916179055565b015190503880613bc3565b90601f19831695613bfa85600052602060002090565b926000905b888210613c3757505083600195969710613c1e575b505050811b019055565b015160001960f88460031b161c19169055388080613c14565b80600185968294968601518155019501930190613bff565b80518210156114955760209160051b010190565b15613c6a57565b60405162461bcd60e51b815260206004820152601a60248201527f54617267657420636861696e206e6f7420737570706f727465640000000000006044820152606490fd5b601c54600160401b811015610661576001810180601c5581101561149557601c6000527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110155565b601e54600160401b811015610661576001810180601e5581101561149557601e600052600080516020615efa8339815191520155565b90815491600160401b8310156106615782613d509160016107139501815561149a565b90919082549060031b91821b91600019901b1916179055565b9081526001600160a01b039091166020820152606060408201819052610aaf92910190610957565b604090610aaf9392815281602082015201906114f1565b33600090815260208190526040902092949392909190613dc7906111c8565b613dd28115156135dd565b613dec61117961117285600052601d602052604060002090565b613dfc6301e1338087111561366b565b613e8f60175496613e0f6111e2896136aa565b613e83613e2689600052601b602052604060002090565b97898955613e61600195613e3c88888d01613b81565b600060028c0155600060038c0155613e5b60048c0160ff198154169055565b42613250565b60058a01556006890180546001600160a01b0319163317905560078901613b81565b84600888015542613250565b94600a8101958655613eae613ea3436131f4565b65ffffffffffff1690565b8061401c5750819060005b600b820155600960009101925b613fc7575b505050613fa5613fc1937fdb17271edb72bcaba16ce918d885db2e701491c9ff3f713f80caf9d614aa9ff4613f957ff46a1614ca62096cf230d10ea203eb985f7a60d98cdffc807d794181bc0a9f9a97957f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd637f5d1231ca3a274bcd2f510e0d53a889213ebf0315b86ee6bb9d73da08fba7460696613f688c613caf565b8b613f7a604051928392339084613d69565b0390a1604080518b8152602081019290925290918291820190565b0390a16040519182918883613d91565b0390a15460408051858152602081019290925290918291820190565b0390a190565b85518110156140175780613ffd613ff8611172613fe7614011958b613c4f565b51600052601d602052604060002090565b613c63565b611fc561400a8289613c4f565b5185613d2d565b81613ec6565b613ecb565b61402590613226565b908291613eb9565b1561403457565b60405162461bcd60e51b815260206004820152601760248201527f50726f706f73616c20646f6573206e6f742065786973740000000000000000006044820152606490fd5b1561408057565b60405162461bcd60e51b815260206004820152600c60248201526b159bdd1a5b99c8195b99195960a21b6044820152606490fd5b156140bb57565b60405162461bcd60e51b815260206004820152601960248201527f50726f706f73616c20616c7265616479206578656375746564000000000000006044820152606490fd5b1561410757565b60405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b6044820152606490fd5b1561414357565b60405162461bcd60e51b815260206004820152601660248201527557726f6e6720636861696e20666f7220766f74696e6760501b6044820152606490fd5b6002600b5414614192576002600b55565b604051633ee5aeb560e01b8152600490fd5b90600a820291808304600a149015171561139257565b8181029291811591840414171561139257565b9081600052601b6020526141e860406000209283541461402d565b60028201546003830154928382019081831161139257600b015460649061421f906001600160d01b03906113509061134b90612a8c565b04111592839182614231575b50509190565b119050388061422b565b1561424257565b606460405162461bcd60e51b815260206004820152602060248201527f45786563757465206f6e6c7920696e20676f7665726e616e636520636861696e6044820152fd5b1561428d57565b60405162461bcd60e51b815260206004820152602760248201527f566f74696e67206e6f7420656e64656420616e642071756f72756d206e6f74206044820152661c995858da195960ca1b6064820152608490fd5b156142e957565b60405162461bcd60e51b8152602060048201526013602482015272141c9bdc1bdcd85b081b9bdd081c185cdcd959606a1b6044820152606490fd5b1561432b57565b60405162461bcd60e51b8152602060048201526014602482015273151a5b595b1bd8dac81b9bdd08195e1c1a5c995960621b6044820152606490fd5b919082526020916040838201526000928254614382816103e3565b9384604085015260019182811690816000146143e457506001146143a9575b505050505090565b6000908152828120949550935b8585106143d05750505060609250010138808080806143a1565b8054858501606001529382019381016143b6565b93505050506060935060ff929192191683830152151560051b010138808080806143a1565b1561441057565b60405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48195e1958dd5d195960821b6044820152606490fd5b1561444f57565b60405162461bcd60e51b815260206004820152600e60248201526d27b7363c9034b734ba34b0ba37b960911b6044820152606490fd5b1561448c57565b60405162461bcd60e51b815260206004820152602360248201527f496e73756666696369656e7420766f74696e6720706f77657220746f2063616e60448201526218d95b60ea1b6064820152608490fd5b91926060938192845260406020850152816040850152848401376000828201840152601f01601f1916010190565b1561451257565b60405162461bcd60e51b815260206004820152602760248201527f50726f706f73616c20616c726561647920657865637574656420696e20746869604482015266399031b430b4b760c91b6064820152608490fd5b1561456e57565b60405162461bcd60e51b815260206004820152602760248201527f557365206578656375746550726f706f73616c20696e20676f7665726e616e63604482015266329031b430b4b760c91b6064820152608490fd5b156145ca57565b60405162461bcd60e51b8152602060048201526014602482015273436861696e206e6f7420696e207461726765747360601b6044820152606490fd5b1561460d57565b60405162461bcd60e51b815260206004820152600e60248201526d426164207369676e61747572657360901b6044820152606490fd5b91908110156114955760051b81013590601e1981360301821215610a995701908135916001600160401b038311610a99576020018236038113610a99579190565b91908110156114955760051b0190565b35610aaf81610bc2565b156146a557565b60405162461bcd60e51b815260206004820152600d60248201526c426164207369676e617475726560981b6044820152606490fd5b156146e157565b60405162461bcd60e51b815260206004820152601060248201526f223ab83634b1b0ba329039b4b3b732b960811b6044820152606490fd5b1561472057565b60405162461bcd60e51b815260206004820152601b60248201527f4e6f20766f74696e6720706f77657220617420736e617073686f7400000000006044820152606490fd5b1561476c57565b60405162461bcd60e51b815260206004820152601a60248201527f51756f72756d206e6f74207265616368656420627920736967730000000000006044820152606490fd5b8151610aaf92612d619260401983016147e9576147e292506020820151906060604084015193015160001a90612d6a565b9192909190565b505060009160029190565b61480d600091808352601b60205260408320541461402d565b80601e54915b82811061482257505050600190565b61484261482e8261485b565b600052601d60205260ff6040600020541690565b1561485557614850906136aa565b614813565b50905090565b601e5481101561487e57601e600052600080516020615efa833981519152015490565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c6d0c2d2dc40d2dcc8caf606b1b6044820152606490fd5b909291926148c68161107f565b916148d460405193846106b7565b829482845282820111610a99576020610713930190610934565b9190604083820312610a995782516001600160e01b031981168103610a9957926020810151906001600160401b038211610a9957019080601f83011215610a99578151610aaf926020016148b9565b90816020910312610a99575190565b9190826040910312610a995760208251920151610aaf81610bc2565b9080601f83011215610a99578151610aaf926020016148b9565b9080601f83011215610a995781519061499a826120c4565b926149a860405194856106b7565b828452602092838086019160051b83010192808411610a9957848301915b8483106149d65750505050505090565b82516001600160401b038111610a995786916149f784848094890101614968565b8152019201916149c6565b91909161010081840312610a99578051916001600160401b0392838111610a995784614a2f918401614968565b936020830151848111610a995781614a48918501614968565b936040840151818111610a995782614a61918601614968565b936060810151828111610a995783614a7a918301614968565b9360808201519360a08301519360c0840151908111610a995760e091614aa1918501614982565b92015190565b614abb6020918280825183010191016148ee565b91906001600160e01b031916630236fce560e51b8103614afa57508181614aeb9261071394518301019101614a02565b96959095949194939293615206565b63f0f9e6b760e01b8103614b2357508181614b1e926107139451830101910161493d565b615304565b632ab43f7f60e11b8103614b4c57508181614b47926107139451830101910161493d565b6153a4565b6304fa45bf60e31b8103614b7f57508181614b70926107139451830101910161494c565b6001600160a01b031690615501565b633972e9fb60e21b8103614ba857508181614ba3926107139451830101910161493d565b6155b1565b63093f734560e31b8103614bd157508181614bcc926107139451830101910161493d565b614c44565b633e78500160e21b8103614bfa57508181614bf5926107139451830101910161493d565b614ddf565b633cdb568760e11b14915061071390505760405162461bcd60e51b81526020600482015260116024820152702ab735b737bbb71037b832b930ba34b7b760791b6044820152606490fd5b80600052601d60205260ff60406000205416614cf2576018548114614cad57614ca881614c9f610cef7fbba9d55e9fd1a441b1617724e2fdb76777d15ec77ab2b72ac15952cbe97085db94600052601d602052604060002090565b6121c581613cf7565b0390a1565b60405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206164642063757272656e7420636861696e00000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f436861696e20616c726561647920737570706f727465640000000000000000006044820152606490fd5b15614d3e57565b60405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742072656d6f76652063757272656e7420636861696e00000000006044820152606490fd5b601e548015614dc95760001981019080821015611495577f50bb669a95c7b50b7e8a6f09454034b2b14cf2b85c730dca9a539ca82cb6e34f600091601e83520155601e55565b634e487b7160e01b600052603160045260246000fd5b614dff60ff614df883600052601d602052604060002090565b5416613629565b614e0d601854821415614d37565b614e2e614e2482600052601d602052604060002090565b805460ff19169055565b60005b601e5480821015614eb55782614e53614e4984611470565b90549060031b1c90565b14614e675750614e62906136aa565b614e31565b91614ead614ca892613d50614ea7614e49614ea27f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d598613226565b611470565b91611470565b6121c5614d83565b5050614ca87f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d5916121c5565b15614ee857565b60405162461bcd60e51b815260206004820152601660248201527553796d626f6c2063616e6e6f7420626520656d70747960501b6044820152606490fd5b15614f2d57565b60405162461bcd60e51b815260206004820152601860248201527f4c6f636174696f6e2063616e6e6f7420626520656d70747900000000000000006044820152606490fd5b15614f7957565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b210353ab934b9b234b1ba34b7b760611b6044820152606490fd5b15614fbc57565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964204f4b544d4f60981b6044820152606490fd5b15614ff857565b60405162461bcd60e51b815260206004820152600b60248201526a0496e76616c6964204b50560ac1b6044820152606490fd5b805190600160401b821161066157601254826012558083106150a3575b5060126000526020908101907fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34446000925b848410615087575050505050565b6001838261509783945186613b81565b01920193019290615079565b600060128152837fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344492830192015b8281106150df575050615048565b806150ec600192546103e3565b806150f9575b50016150d1565b601f9081811184146151115750508281555b386150f2565b836151339261512585600052602060002090565b920160051c820191016136b9565b6000818152602081208183555561510b565b9897969495926151889061517a61516a6151969597948d610100908181520190610957565b6020978d89818403910152610957565b908b820360408d0152610957565b9089820360608b0152610957565b93608088015260a087015285830360c08701528151908184528084019381808460051b8301019401946000915b8483106151d857505050505060e09150930152565b909192939484806151f5600193601f198682030187528a51610957565b9801930193019195949392906151c3565b94909591939692968551156152c8577f62d6efdb8dbca656ac38d327c1d66a4ccaeabc91c464fe5e7352b604858f5f4697614ca89561524789511515614ee1565b61525381511515614f26565b61525e831515614f72565b615269841515614fb5565b615274861515614ff1565b61527d88613825565b615286896138fc565b61528f816139d3565b61529882613aaa565b6152a183601055565b6152aa84601155565b6152b38561502b565b6152bc86601355565b60405198899889615145565b60405162461bcd60e51b81526020600482015260146024820152734e616d652063616e6e6f7420626520656d70747960601b6044820152606490fd5b80151580615399575b156153545760168054908290556040805191825260208201929092527fd0198ea88bf9c4ad5317b68e697944e524541fcb494d854f095b1cd88a097ab69181908101614ca8565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642071756f72756d2070657263656e74616765000000000000006044820152606490fd5b50606481111561530d565b80600052601d6020526153be60ff60406000205416613629565b601854908181146154095760188190556040805192835260208301919091527f979103c7afbf0138fe781172504ceb318ff78f9a420de8cabac8141f0121b521919081908101614ca8565b60405162461bcd60e51b815260206004820152600d60248201526c14d85b594818da185a5b881251609a1b6044820152606490fd5b1561544557565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b1561548057565b60405162461bcd60e51b81526020600482015260156024820152744d6f64756c6520616c72656164792065786973747360581b6044820152606490fd5b156154c457565b60405162461bcd60e51b8152602060048201526015602482015274135bd91d5b1948191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606490fd5b7ff14475b19484bf096265507cc0c41cd3bf1994992088806830686e2d7272271991906155386001600160a01b038316151561543e565b80600052601a60205261555360ff6040600020541615615479565b600081815260196020526040902080546001600160a01b0319166001600160a01b038416179055601a602090815260406000819020805460ff1916600117905580519283526001600160a01b03909316908201529081908101614ca8565b60207f4c7c76abe482a2c36ea52f1b999474c69f8b4afeeac5635f8aea2526864ba8539180600052601a82526155ee60ff604060002054166154bd565b600081815260198352604080822080546001600160a01b0319169055601a845290819020805460ff1916905551908152a1565b6012549061562e826120c4565b91604061563d815194856106b7565b8184528360208091019160126000527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444906000935b85851061568157505050505050565b600184819284516156968161292b818a610599565b815201930194019391615672565b9060405191828154918282526020928383019160005283600020936000905b8282106156d957505050610713925003836106b7565b8554845260019586019588955093810193909101906156c3565b601c9081549283821015615792578101918282116113925783831161578a575b818303838111611392576157269061300f565b93825b84811061573857505050505090565b81811015611495576157859083600052807f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a211015461577f6157798784613235565b89613c4f565b526136aa565b615729565b839250615713565b50505050610aaf612fe7565b6157b281600052601b602052604060002090565b906157bf8183541461402d565b600482015460ff8160081c1661586e5760ff16615867576157df906141cd565b60058301544210828115948161585f575b81615850575b506158475782918261582e575b5050615827578161581e575b5061581957600090565b600290565b9050153861580f565b5050600190565b8492509061583f575b503880615803565b905038615837565b50505050600590565b600a91500154421015386157f6565b8391506157f0565b5050600390565b505050600490565b9060005b6009830180548210156158b85761589282849261149a565b90549060031b1c146158b0576158a96009916136aa565b905061587a565b505050600190565b50505050600090565b6001600160a01b0390811692918190841561594d575b16908115615905575b6107139360005260086020528060406000205416916000526040600020541690615992565b61590e83615b1a565b93615918436131f4565b6001600160d01b0395868061592b6134ac565b1691169003958611611392576107139561594491615c04565b505093506158e0565b905061595883615b1a565b90615962436131f4565b6001600160d01b039283806159756134ac565b1691160192831161139257839261598b91615c04565b50506158d7565b6001600160a01b03808316939291908116908185141580615adb575b6159ba575b5050505050565b81615a3f575b5050826159cf575b80806159b3565b6001600160a01b031660009081526009602052604090207fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72491615a1c91615a169091615b1a565b90615ae4565b604080516001600160d01b039384168152919092166020820152a23880806159c8565b6001600160a01b03166000908152600960205260409020615a5f84615b1a565b615a68436131f4565b6001600160d01b03918280615a7c866134f6565b169116900392828411611392577fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72493615ad192615ab892615ced565b6040805192851683529316602082015291829190820190565b0390a238806159c0565b508315156159ae565b90615aee436131f4565b6001600160d01b03918280615b02866134f6565b1691160191821161139257615b1692615ced565b9091565b6001600160d01b0390818111615b2e571690565b604490604051906306dfcc6560e41b825260d060048301526024820152fd5b600a5490600160401b821015610661576001820180600a5582101561149557600a600052805160209091015160301b65ffffffffffff191665ffffffffffff9190911617600080516020615eba83398151915290910155565b8054600160401b81101561066157615bc39160018201815561149a565b615bee57815160209092015160301b65ffffffffffff191665ffffffffffff92909216919091179055565b634e487b7160e01b600052600060045260246000fd5b600a549192918015615cc357615c1c615c3491613226565b600a600052600080516020615eba8339815191520190565b9081549165ffffffffffff90818416918316808311615cb157869203615c7957615c7292509065ffffffffffff82549181199060301b169116179055565b60301c9190565b5050615cac90615c98615c8a611072565b65ffffffffffff9092168252565b6001600160d01b0385166020820152615b4d565b615c72565b604051632520601d60e01b8152600490fd5b50615ce790615cd3615c8a611072565b6001600160d01b0384166020820152615b4d565b60009190565b80549293928015615d8457615d04615d1191613226565b8260005260206000200190565b9182549265ffffffffffff91828516928116808411615cb157879303615d505750615c7292509065ffffffffffff82549181199060301b169116179055565b915050615cac91615d70615d62611072565b65ffffffffffff9093168352565b6001600160d01b0386166020830152615ba6565b5090615ce791615d95615d62611072565b6001600160d01b0385166020830152615ba6565b6001600160a01b03808316929181811690848203615e3e57600082815260086020526040902080546001600160a01b031981166001600160a01b038716179091556107139593169392615e389285907f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f600080a46001600160a01b031660009081526020819052604090205490565b91615992565b60405162461bcd60e51b815260206004820152601360248201527211195b1959d85d1a5bdb88191a5cd8589b1959606a1b6044820152606490fdfedf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7bb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fdc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8d7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb550bb669a95c7b50b7e8a6f09454034b2b14cf2b85c730dca9a539ca82cb6e3508d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802a2646970667358221220342bb23de0ffd74d2c73ab1bca80be5afb39937e0bdb34deb68fe801c38061eb64736f6c63430008140033bb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444c65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724", + "deployedBytecode": "0x6080604052600436101561001257600080fd5b60003560e01c8063013cf08b146103de57806306fdde03146103d9578063078f6208146103d4578063095ea7b3146103cf5780630c0512e9146103ca5780630d61b519146103c557806318160ddd146103c0578063204c5d1f146103bb57806322dbefbb1461030c57806322f3e2d4146103b657806323b872dd146103b15780632519ae5c146103ac578063313ce567146103a75780633644e515146103a25780633a46b1a8146102d557806347c661401461039d5780634b145793146103075780634bf5d7e9146103985780634cf2ab32146103935780634cfd16bb1461038e5780634de184f6146103845780634fa76ec9146103895780635221c1f014610384578063548d496f1461037f578063587cde1e1461037a5780635c19a95c146103755780635cf0e8a4146103705780636cbadbfa146103705780636dcf811d1461036b5780636fcfff451461036657806370a08231146103615780637ce288ea1461035c5780637e5a9b47146103575780637ecebe00146103525780637f6dda141461034d57806384b0196e1461034857806385e59ce2146103435780638e539e8c1461033e5780639080936f1461033957806391ddadf41461033457806395d89b411461032f57806398e527d31461032a5780639a49bdde146103255780639ab24eb014610320578063a351f6151461031b578063a9059cbb14610316578063adf7420714610311578063b0b6cc1a1461030c578063b3fe8bcb14610307578063c3cda52014610302578063c8a6d06e146102fd578063c97bfe6b146102f8578063c9a3c0c7146102f3578063c9d27afe146102ee578063d505accf146102e9578063dcf628c0146102e4578063dd62ed3e146102df578063e49a62e9146102da578063eaeded5f146102d5578063eced3dfb146102d0578063f1127ed8146102cb5763f2c26a47146102c657600080fd5b6128bb565b612795565b612777565b6112d6565b612759565b6126f6565b612659565b6124a8565b61235b565b612226565b6121d5565b612139565b611ff7565b611397565b610f45565b611ce7565b611c8d565b611b4f565b611b06565b611ae8565b611aca565b611a23565b6119f7565b6119ce565b61199c565b611965565b6118a3565b61186d565b611830565b611802565b611777565b61173a565b6116cd565b6116aa565b61168c565b611664565b611625565b6115f4565b61159f565b6115d6565b611525565b6114b2565b6113c8565b611301565b6112b3565b611297565b6110ec565b610fb0565b610f79565b610e62565b610d32565b610c26565b610c08565b610bd3565b610b93565b610ab2565b6109f5565b90600182811c92168015610413575b60208310146103fd57565b634e487b7160e01b600052602260045260246000fd5b91607f16916103f2565b600d546000929161042d826103e3565b80825291600190818116908115610492575060011461044b57505050565b91929350600d600052600080516020615eda833981519152916000925b84841061047a57505060209250010190565b80546020858501810191909152909301928101610468565b915050602093945060ff929192191683830152151560051b010190565b600e54600092916104bf826103e3565b8082529160019081811690811561049257506001146104dd57505050565b91929350600e600052600080516020615e9a833981519152916000925b84841061050c57505060209250010190565b805460208585018101919091529093019281016104fa565b600f5460009291610534826103e3565b80825291600190818116908115610492575060011461055257505050565b91929350600f600052600080516020615f1a833981519152916000925b84841061058157505060209250010190565b8054602085850181019190915290930192810161056f565b90600092918054916105aa836103e3565b91828252600193848116908160001461060c57506001146105cc575b50505050565b90919394506000526020928360002092846000945b8386106105f85750505050010190388080806105c6565b8054858701830152940193859082016105e1565b9294505050602093945060ff191683830152151560051b010190388080806105c6565b634e487b7160e01b600052604160045260246000fd5b61014081019081106001600160401b0382111761066157604052565b61062f565b604081019081106001600160401b0382111761066157604052565b60a081019081106001600160401b0382111761066157604052565b60c081019081106001600160401b0382111761066157604052565b90601f801991011681019081106001600160401b0382111761066157604052565b60405190600082600c54916106ec836103e3565b808352926001908181169081156107625750600114610715575b50610713925003836106b7565b565b600c60009081529150600080516020615e7a8339815191525b8483106107475750610713935050810160200138610706565b81935090816020925483858a0101520191019091859261072e565b90506020925061071394915060ff191682840152151560051b82010138610706565b60405190600082600d5491610798836103e3565b8083529260019081811690811561076257506001146107be5750610713925003836106b7565b600d60009081529150600080516020615eda8339815191525b8483106107f05750610713935050810160200138610706565b81935090816020925483858a010152019101909185926107d7565b60405190600082600e549161081f836103e3565b8083529260019081811690811561076257506001146108455750610713925003836106b7565b600e60009081529150600080516020615e9a8339815191525b8483106108775750610713935050810160200138610706565b81935090816020925483858a0101520191019091859261085e565b60405190600082600f54916108a6836103e3565b8083529260019081811690811561076257506001146108cc5750610713925003836106b7565b600f60009081529150600080516020615f1a8339815191525b8483106108fe5750610713935050810160200138610706565b81935090816020925483858a010152019101909185926108e5565b9061071361092d9260405193848092610599565b03836106b7565b60005b8381106109475750506000910152565b8181015183820152602001610937565b9060209161097081518092818552858086019101610934565b601f01601f1916010190565b989490936109a86109e4989497936101609c9f9e9d9a968c5260208c61018091829101528c0190610957565b60408b019790975260608a015215156080890152151560a088015260c08701526001600160a01b031660e0860152848203610100860152610957565b956101208301526101408201520152565b34610a99576020366003190112610a9957600435600052601b60205260406000208054610a9560405191610a3783610a308160018801610599565b03846106b7565b600284015460038501546004860154600587015460068801549397929492936001600160a01b031690610a6c60078601610919565b92600886015494600b600a880154970154976040519b8c9b60ff808660081c169516938d61097c565b0390f35b600080fd5b906020610aaf928181520190610957565b90565b34610a9957600080600319360112610b90576040519080600354610ad5816103e3565b80855291600191808316908115610b665750600114610b0b575b610a9585610aff818703826106b7565b60405191829182610a9e565b9250600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610b4e575050508101602001610aff82610a95610aef565b80546020858701810191909152909301928101610b33565b869550610a9596935060209250610aff94915060ff191682840152151560051b8201019293610aef565b80fd5b34610a99576000366003190112610a99576060601654601854601e549060405192835260208301526040820152f35b6001600160a01b03811603610a9957565b34610a99576040366003190112610a9957610bfd600435610bf381610bc2565b6024359033612bf5565b602060405160018152f35b34610a99576000366003190112610a99576020601754604051908152f35b34610a99576020366003190112610a99577fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d26004356007610c7182600052601b602052604060002090565b610c7d8382541461402d565b610cfc60048201610c9e610c99610c95835460ff1690565b1590565b6140b4565b610caf60185460088501541461423b565b610cdf610cbb866141cd565b60058601544210801590610d2b575b610cd390614286565b81610d23575b506142e2565b610cef600a840154421015614324565b805460ff19166001179055565b0190610d0f610d0a83610919565b614aa7565b610d1e60405192839283614367565b0390a1005b905038610cd9565b5080610cca565b34610a99576000366003190112610a99576020600254604051908152f35b90815180825260208092019182818360051b85019501936000915b848310610d7b5750505050505090565b9091929394958480610d9583856001950387528a51610957565b9801930193019194939290610d6b565b610aaf90602081528251610e3d610dca61014092836020860152610160850190610957565b610e14610e00610dec602089015193601f1994858983030160408a0152610957565b604089015184888303016060890152610957565b606088015183878303016080880152610957565b90608087015160a086015260a087015160c086015260c0870151908583030160e0860152610d50565b9360e08101516101009081850152810151906101209182850152015191019015159052565b34610a9957600080600319360112610b9057610a9590610f39604051610e8781610645565b60609283825283602083015283604083015283808301528060808301528060a08301528360c08301528060e083015261010090808284015261012080930152610ece611065565b93610ed76106d8565b8552610ee1610784565b6020860152610eee61080b565b6040860152610efb610892565b90850152601054608085015260115460a0850152610f17615621565b60c085015260135460e08501526014549084015260155460ff16151590830152565b60405191829182610da5565b34610a99576020366003190112610a99576004356000526019602052602060018060a01b0360406000205416604051908152f35b34610a99576000366003190112610a995760ff601f54161580610fa4575b6020906040519015158152f35b5060155460ff16610f97565b34610a99576060366003190112610a9957600435610fcd81610bc2565b602435610fd981610bc2565b6001600160a01b03821660009081526001602090815260408083203384529091529020604435919054926000198410611023575b6110179350612ae3565b60405160018152602090f35b82841061103f5761103a8361101795033383612ca9565b61100d565b604051637dc7a0d960e11b81523360048201526024810185905260448101849052606490fd5b6040519061071382610645565b6040519061071382610666565b6001600160401b03811161066157601f01601f191660200190565b9291926110a68261107f565b916110b460405193846106b7565b829481845281830111610a99578281602093846000960137010152565b9080601f83011215610a9957816020610aaf9335910161109a565b34610a995760a0366003190112610a99576004356001600160401b038111610a995761111f610a959136906004016110d1565b7f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd636112846044359261127660643561115681610bc2565b61117e611179611172608435600052601d602052604060002090565b5460ff1690565b613629565b6111926001600160a01b038216151561543e565b6111b46111af610c9561117289600052601a602052604060002090565b615479565b3360009081526020819052604090206111d0905b541515613585565b6007601754966111e76111e2896136aa565b601755565b6112706111fe89600052601b602052604060002090565b9189835561120f8760018501613b81565b61121b60243542613250565b60058401556006830180546001600160a01b031916331790556040516304fa45bf60e31b602082015260248101919091526001600160a01b03909416604485015283606481015b03601f1981018552846106b7565b01613b81565b604051918291338684613d69565b0390a16040519081529081906020820190565b34610a99576000366003190112610a9957602060405160128152f35b34610a99576000366003190112610a995760206112ce612ea7565b604051908152f35b34610a99576040366003190112610a995760206112ce6004356112f881610bc2565b602435906129d2565b34610a99576020366003190112610a995760043580600052601b60205261132f60406000209182541461402d565b606461135a60018060d01b0361135061134b600b860154612a8c565b61325d565b16601654906141ba565b049060036002820154910154918282019081831161139257604080519384526020840194909452928201526060810191909152608090f35b612acd565b34610a99576020366003190112610a9957600435600052601a602052602060ff604060002054166040519015158152f35b34610a99576000366003190112610a99576113e2436131f4565b65ffffffffffff806113f3436131f4565b1691160361144857610a9560405161140a81610666565b601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c740000006020820152604051918291602083526020830190610957565b6040516301bfc1c560e61b8152600490fd5b634e487b7160e01b600052603260045260246000fd5b601e5481101561149557601e600052600080516020615efa8339815191520190600090565b61145a565b80548210156114955760005260206000200190600090565b34610a99576020366003190112610a9957600435601e54811015610a9957602090601e600052600080516020615efa8339815191520154604051908152f35b90815180825260208080930193019160005b828110611511575050505090565b835185529381019392810192600101611503565b34610a99576000366003190112610a995760405180601e54808252826020809301601e600052600080516020615efa8339815191529260005b8582821061158957505050611575925003836106b7565b610a956040519282849384528301906114f1565b855484526001958601958895509301920161155e565b34610a99576020366003190112610a995760206115cc600435600052601d60205260ff6040600020541690565b6040519015158152f35b34610a99576000366003190112610a99576020601654604051908152f35b34610a99576020366003190112610a9957600435600052601d602052602060ff604060002054166040519015158152f35b34610a99576020366003190112610a9957602060043561164481610bc2565b60018060a01b038091166000526008825260406000205416604051908152f35b34610a99576020366003190112610a995761168a60043561168481610bc2565b33615da9565b005b34610a99576000366003190112610a99576020601854604051908152f35b34610a99576000366003190112610a9957602060ff601f54166040519015158152f35b34610a99576020366003190112610a99576004356116ea81610bc2565b6001600160a01b031660009081526009602052604090205463ffffffff9081811161171b5760209160405191168152f35b604490604051906306dfcc6560e41b8252602060048301526024820152fd5b34610a99576020366003190112610a995760206112ce60043561175c81610bc2565b6001600160a01b031660009081526020819052604090205490565b34610a99576020366003190112610a9957600435611794816147f4565b156117c65760207f57df5a6a467271f04b10f7fe9e66d21dcd8ae7eaf079099d48959f24a53b691091604051908152a1005b60405162461bcd60e51b81526020600482015260146024820152734e6f7420616c6c20636861696e7320726561647960601b6044820152606490fd5b34610a99576020366003190112610a995760406118206004356141cd565b8251911515825215156020820152f35b34610a99576020366003190112610a995760043561184d81610bc2565b60018060a01b031660005260076020526020604060002054604051908152f35b34610a99576040366003190112610a9957610a9561188f6024356004356156f3565b6040519182916020835260208301906114f1565b34610a99576000366003190112610a99576119366118e07f0000000000000000000000000000000000000000000000000000000000000000613041565b610a9561190c7f000000000000000000000000000000000000000000000000000000000000000061313a565b611944611917612fe7565b91604051958695600f60f81b875260e0602088015260e0870190610957565b908582036040870152610957565b90466060850152306080850152600060a085015283820360c08501526114f1565b34610a99576020366003190112610a9957602060646119936001600160d01b0361135061134b600435612a8c565b04604051908152f35b34610a99576020366003190112610a995760206001600160d01b036119c561134b600435612a8c565b16604051908152f35b34610a99576020366003190112610a995760206119ec60043561579e565b60ff60405191168152f35b34610a99576000366003190112610a99576020611a13436131f4565b65ffffffffffff60405191168152f35b34610a9957600080600319360112610b90576040519080600454611a46816103e3565b80855291600191808316908115610b665750600114611a6f57610a9585610aff818703826106b7565b9250600483527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410611ab2575050508101602001610aff82610a95610aef565b80546020858701810191909152909301928101611a97565b34610a99576000366003190112610a99576020601c54604051908152f35b34610a99576020366003190112610a995760206112ce60043561485b565b34610a99576020366003190112610a9957600435611b2381610bc2565b6001600160a01b031660009081526009602090815260409091206001600160d01b03906119c5906134f6565b34610a99576040366003190112610a99576004356001600160401b03602435818111610a995736602382011215610a99578060040135918211610a99573660248383010111610a9957610d1e60249284611c7f611bd77fc7c129e53e59dadfa16305619e80c7519f1f6912c10915359fd75b56bcecdd7b97600052601b602052604060002090565b611be38382541461402d565b611c70600b6004830192611c03611bfe60ff86541615151590565b614409565b611c1260058201544210614079565b6006810154611c3c90611c35906001600160a01b03165b6001600160a01b031690565b3314614448565b0154611c69611c4b82336129d2565b916001600160d01b0390611c629061134b90612a8c565b16916141a4565b1015614485565b805461ff001916610100179055565b6040519485940190846144dd565b34610a99576040366003190112610a9957610bfd600435611cad81610bc2565b6024359033612ae3565b9181601f84011215610a99578235916001600160401b038311610a99576020808501948460051b010111610a9957565b34610a99576060366003190112610a99576001600160401b03600435602435828111610a9957611d1b903690600401611cb7565b92604435908111610a995783611d3684923690600401611cb7565b611d3e614181565b611d5284600052601b602052604060002090565b90611d5f8583541461402d565b6004820192611d7a611d75610c95865460ff1690565b61450b565b60185494611d8e6008850154871415614567565b611da0611d9b8786615876565b6145c3565b611db0600a850154421015614324565b611dbb838214614606565b611e45876007860197611e3d600b611dd28b610919565b6020815191012098015497611e2f896040519485936020850197889094939260809260a08301967f45de75acfcd4cbcc5691559486749bf0d5eb65e4b24c59ac2f258ba6bfceaa3484526020840152604083015260608201520152565b03601f1981018352826106b7565b519020612fc1565b9760009889945b838610611f0d575050507fda7dba8f94d70cde423cce3a243bebf95d2ec927507b566f67e329dcfe2d06bb877fbadbd87941bb6424ed4aa4719bf01a3319b64480e49f89018c718603239553d2611ee689611ecd8a610cef8f611ec6611ebf8e61135061134b60018060d01b0392612a8c565b6064900490565b1115614765565b611ed9610d0a82610919565b6040519182918583614367565b0390a1601854604080519283526020830191909152819081015b0390a161168a6001600b55565b909192939499868b611f49611c29611f44611f3c611f36611f2f868a8f614643565b369161109a565b896147b1565b938a8a614684565b614694565b6001600160a01b03821690611f5f90821461469e565b8d88886000925b8310611fa2575050505091611f81611f9292611f98946129d2565b90611f8d821515614719565b613250565b9a6136aa565b9493929190611e4c565b8394955092611fbe611c29611f4485611fc595611fca98614684565b14156146da565b6136aa565b90899291888f8990611f66565b6064359060ff82168203610a9957565b6084359060ff82168203610a9957565b34610a995760c0366003190112610a995760043561201481610bc2565b60443590602435612023611fd7565b8342116120ab5761209f61168a946120a6926040519060208201927fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf845260018060a01b038816604084015286606084015260808301526080825261208782610681565b61209a60a4359360843593519020612fc1565b612d52565b9182612cfc565b615da9565b604051632341d78760e11b815260048101859052602490fd5b6001600160401b0381116106615760051b60200190565b81601f82011215610a99578035916120f2836120c4565b9261210060405194856106b7565b808452602092838086019260051b820101928311610a99578301905b82821061212a575050505090565b8135815290830190830161211c565b34610a995760c0366003190112610a99576001600160401b03600435818111610a995761216a9036906004016110d1565b90604435818111610a995736602382011215610a995761219490369060248160040135910161109a565b608435918211610a9957610a95926121b36121c59336906004016120db565b9060a435926064359160243590613da8565b6040519081529081906020820190565b34610a99576020366003190112610a9957600435601c54811015610a9957602090601c6000527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110154604051908152f35b34610a99576080366003190112610a99576004356001600160401b038111610a9957612259610a959136906004016110d1565b7f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd636112846044359261229d611179611172606435600052601d602052604060002090565b6122bc6122b761117286600052601a602052604060002090565b6154bd565b3360009081526020819052604090206122d4906111c8565b6112766112626007601754966122ec6111e2896136aa565b61127061230389600052601b602052604060002090565b918983556123148760018501613b81565b61232060243542613250565b60058401556006830180546001600160a01b03191633179055604051633972e9fb60e21b602082015260248101919091529384906044820190565b34610a99576040366003190112610a99576004356024358015158103610a99577f78975aaf742630489badd22949b88ac50eaaea576339ee05440b671a33bfb6a9916123a5614181565b611f006123bc82600052601b602052604060002090565b6123c88382541461402d565b6123d760058201544210614079565b6123eb610c99610c95600484015460ff1690565b600c81019061241a612415610c9561117233869060018060a01b0316600052602052604060002090565b614100565b61242b60185460088301541461413c565b612453610cef61243f600b840154336129d2565b336000908152602095909552604090942090565b841561249357600201612467828254613250565b90555b604080519384523360208501529315159383019390935260608201929092529081906080820190565b6003016124a1828254613250565b905561246a565b34610a995760e0366003190112610a99576004356124c581610bc2565b6024356124d181610bc2565b604435906064356124e0611fe7565b8142116125cb576001600160a01b0385811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019283529283019390935292861660608201526080810187905260a081019190915260c08082019490945292835261258492909161257160e0836106b7565b61209a60c4359360a43593519020612fc1565b6001600160a01b03848116908216036125a1575061168a92612bf5565b6040516325c0072360e11b81526001600160a01b0391821660048201529084166024820152604490fd5b60405163313c898160e11b815260048101839052602490fd5b9895929a97949161260a90610aaf9d9b9895928b526101808060208d01528b0190610957565b60408a019b909b52606089015215156080880152151560a087015260c08601526001600160a01b031660e0850152610100840152610120830152610140820152808303610160909101526114f1565b34610a99576020366003190112610a995760043580600052601b6020526040600020612688815492831461402d565b610a95600282015492600383015490600484015460058501546126b4600687015460018060a01b031690565b600887015491600a88015493600b890154956126de60096126d760018d01610919565b9b016156a4565b976040519b8c9b60ff808660081c169516938d6125e4565b34610a99576040366003190112610a9957602061275060043561271881610bc2565b6024359061272582610bc2565b60018060a01b03166000526001835260406000209060018060a01b0316600052602052604060002090565b54604051908152f35b34610a99576020366003190112610a995760206115cc6004356147f4565b34610a99576000366003190112610a99576020601e54604051908152f35b34610a99576040366003190112610a99576004356127b281610bc2565b6024359063ffffffff82168203610a9957610a9591612802916127d3612ce3565b506127dc612ce3565b506001600160a01b031660009081526009602052604090206127fc612ce3565b5061149a565b506040519061281082610666565b5465ffffffffffff811680835260309190911c60209283019081526040805192835290516001600160d01b031692820192909252918291820190565b9794999895926128919061288361289f946128756101009b98958d610120908181520190610957565b8c810360208e015290610957565b908a820360408c0152610957565b9088820360608a0152610957565b97608087015260a086015260c085015260e08401521515910152565b34610a9957600080600319360112610b9057604051908181600c546128df816103e3565b808452936001918083169081156129ae5750600114612963575b5050612907925003826106b7565b604051906129188261092d8161041d565b610a956040516129328161292b816104af565b03826106b7565b6040516129428161292b81610524565b601054601154601354916014549360ff6015541695604051998a998a61284c565b9150600c8252600080516020615e7a8339815191525b8483106129935750612907935050810160200138806128f9565b81935090816020925483858901015201910190918492612979565b9150506020925061290794915060ff191682840152151560051b82010138806128f9565b6001600160a01b0316600090815260096020526040812090916129f490612a8c565b81549083829160058411612a3d575b612a0e935084613524565b80612a225750505b6001600160d01b031690565b91612a2f60209293613226565b92815220015460301c612a16565b9192612a4881613381565b810390811161139257612a0e9385875265ffffffffffff808360208a2001541690851610600014612a7a575091612a03565b929150612a8690613242565b90612a03565b65ffffffffffff612a9c436131f4565b1680821015612aaf5750610aaf906131f4565b6044925060405191637669fc0f60e11b835260048301526024820152fd5b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0380821694939291908515612bdc5782168015612bc3576001600160a01b03821660009081526020819052604090205495848710612b945784610713969703612b458460018060a01b03166000526000602052604060002090565b556001600160a01b0384166000908152602081815260409182902080548801905590518681527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a36158c1565b60405163391434e360e21b81526001600160a01b03841660048201526024810188905260448101869052606490fd5b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b6001600160a01b038082169291908315612c90578216938415612c775780612c6d7f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92594612c5660209560018060a01b03166000526001602052604060002090565b9060018060a01b0316600052602052604060002090565b55604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b906001600160a01b0380831615612c9057811615612c7757612c56612ce09260018060a01b03166000526001602052604060002090565b55565b60405190612cf082610666565b60006020838281520152565b6001600160a01b03811660009081526007602052604090208054600181019091559091819003612d2a575050565b6040516301d4b62360e61b81526001600160a01b039092166004830152602482015260449150fd5b91610aaf9391612d6193612d6a565b90929192612e1a565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411612dee57926020929160ff608095604051948552168484015260408301526060820152600092839182805260015afa15612de25780516001600160a01b03811615612dd957918190565b50809160019190565b604051903d90823e3d90fd5b50505060009160039190565b60041115612e0457565b634e487b7160e01b600052602160045260246000fd5b612e2381612dfa565b80612e2c575050565b612e3581612dfa565b60018103612e4f5760405163f645eedf60e01b8152600490fd5b612e5881612dfa565b60028103612e795760405163fce698f760e01b815260048101839052602490fd5b80612e85600392612dfa565b14612e8d5750565b6040516335e2f38360e21b81526004810191909152602490fd5b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480612f98575b15612f02577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a08152612f928161069c565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000004614612ed9565b604290612fcc612ea7565b906040519161190160f01b8352600283015260228201522090565b604051602081018181106001600160401b038211176106615760405260008152906000368137565b90613019826120c4565b61302660405191826106b7565b8281528092613037601f19916120c4565b0190602036910137565b60ff811461307f5760ff811690601f821161306d576040519161306383610666565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554816000613092836103e3565b8083529260019081811690811561311857506001146130b9575b50610aaf925003826106b7565b6005600090815291507f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8483106130fd5750610aaf9350508101602001386130ac565b819350908160209254838589010152019101909184926130e4565b905060209250610aaf94915060ff191682840152151560051b820101386130ac565b60ff811461315c5760ff811690601f821161306d576040519161306383610666565b5060405160065481600061316f836103e3565b8083529260019081811690811561311857506001146131955750610aaf925003826106b7565b6006600090815291507ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f5b8483106131d95750610aaf9350508101602001386130ac565b819350908160209254838589010152019101909184926131c0565b65ffffffffffff90818111613207571690565b604490604051906306dfcc6560e41b8252603060048301526024820152fd5b60001981019190821161139257565b9190820391821161139257565b906001820180921161139257565b9190820180921161139257565b600a80546000816005811161330b575b509290925b8381106132b1575050600091801560001461328f57505050600090565b61329890613226565b9152600080516020615eba833981519152015460301c90565b90928082169080831860011c8201809211611392578360005265ffffffffffff8083600080516020615eba833981519152015416908616106000146132f95750925b90613272565b93915061330590613242565b906132f3565b909161331682613381565b82039182116113925783835265ffffffffffff8083600080516020615eba833981519152015416908616106000146133515750905b3861326d565b915061335c90613242565b61334b565b811561336b570490565b634e487b7160e01b600052601260045260246000fd5b6001811115610aaf57600181600160801b81101561349a575b61344261343861342e61342461341a61341061344e97600488600160401b6134499a101561348d575b640100000000811015613480575b62010000811015613473575b610100811015613467575b601081101561345b575b1015613453575b60030260011c613409818b613361565b0160011c90565b613409818a613361565b6134098189613361565b6134098188613361565b6134098187613361565b6134098186613361565b8093613361565b821190565b900390565b60011b6133f9565b811c9160021b916133f2565b60081c91811b916133e8565b60101c9160081b916133dd565b60201c9160101b916133d1565b60401c9160201b916133c3565b50600160401b9050608082901c61339a565b600a54600090806134be575050600090565b8060001981011161139257600a7fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a79252015460301c90565b80546000918161350857505050600090565b6000199282848101116113925760209181522001015460301c90565b91905b8382106135345750505090565b9091928083169080841860011c82018092116113925760008581526020902082015465ffffffffffff90811690841610156135735750925b9190613527565b93925061357f90613242565b9161356c565b1561358c57565b60405162461bcd60e51b815260206004820152602360248201527f4d75737420686f6c6420746f6b656e7320746f206372656174652070726f706f6044820152621cd85b60ea1b6064820152608490fd5b156135e457565b60405162461bcd60e51b815260206004820152601960248201527f4475726174696f6e206d75737420626520706f736974697665000000000000006044820152606490fd5b1561363057565b60405162461bcd60e51b815260206004820152601360248201527210da185a5b881b9bdd081cdd5c1c1bdc9d1959606a1b6044820152606490fd5b1561367257565b60405162461bcd60e51b815260206004820152601060248201526f54696d656c6f636b20746f6f2062696760801b6044820152606490fd5b60001981146113925760010190565b8181106136c4575050565b600081556001016136b9565b90601f82116136dd575050565b61071391600c600052600080516020615e7a833981519152906020601f840160051c83019310613715575b601f0160051c01906136b9565b9091508190613708565b90601f821161372c575050565b61071391600d600052600080516020615eda833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b90601f8211613770575050565b61071391600e600052600080516020615e9a833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b90601f82116137b4575050565b61071391600f600052600080516020615f1a833981519152906020601f840160051c8301931061371557601f0160051c01906136b9565b9190601f81116137fa57505050565b610713926000526020600020906020601f840160051c8301931061371557601f0160051c01906136b9565b9081516001600160401b0381116106615761384a81613845600c546103e3565b6136d0565b602080601f8311600114613886575081929360009261387b575b50508160011b916000199060031b1c191617600c55565b015190503880613864565b90601f198316946138a7600c600052600080516020615e7a83398151915290565b926000905b8782106138e45750508360019596106138cb575b505050811b01600c55565b015160001960f88460031b161c191690553880806138c0565b806001859682949686015181550195019301906138ac565b9081516001600160401b038111610661576139218161391c600d546103e3565b61371f565b602080601f831160011461395d5750819293600092613952575b50508160011b916000199060031b1c191617600d55565b01519050388061393b565b90601f1983169461397e600d600052600080516020615eda83398151915290565b926000905b8782106139bb5750508360019596106139a2575b505050811b01600d55565b015160001960f88460031b161c19169055388080613997565b80600185968294968601518155019501930190613983565b9081516001600160401b038111610661576139f8816139f3600e546103e3565b613763565b602080601f8311600114613a345750819293600092613a29575b50508160011b916000199060031b1c191617600e55565b015190503880613a12565b90601f19831694613a55600e600052600080516020615e9a83398151915290565b926000905b878210613a92575050836001959610613a79575b505050811b01600e55565b015160001960f88460031b161c19169055388080613a6e565b80600185968294968601518155019501930190613a5a565b9081516001600160401b03811161066157613acf81613aca600f546103e3565b6137a7565b602080601f8311600114613b0b5750819293600092613b00575b50508160011b916000199060031b1c191617600f55565b015190503880613ae9565b90601f19831694613b2c600f600052600080516020615f1a83398151915290565b926000905b878210613b69575050836001959610613b50575b505050811b01600f55565b015160001960f88460031b161c19169055388080613b45565b80600185968294968601518155019501930190613b31565b91909182516001600160401b03811161066157613ba881613ba284546103e3565b846137eb565b602080601f8311600114613be4575081929394600092613bd9575b50508160011b916000199060031b1c1916179055565b015190503880613bc3565b90601f19831695613bfa85600052602060002090565b926000905b888210613c3757505083600195969710613c1e575b505050811b019055565b015160001960f88460031b161c19169055388080613c14565b80600185968294968601518155019501930190613bff565b80518210156114955760209160051b010190565b15613c6a57565b60405162461bcd60e51b815260206004820152601a60248201527f54617267657420636861696e206e6f7420737570706f727465640000000000006044820152606490fd5b601c54600160401b811015610661576001810180601c5581101561149557601c6000527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110155565b601e54600160401b811015610661576001810180601e5581101561149557601e600052600080516020615efa8339815191520155565b90815491600160401b8310156106615782613d509160016107139501815561149a565b90919082549060031b91821b91600019901b1916179055565b9081526001600160a01b039091166020820152606060408201819052610aaf92910190610957565b604090610aaf9392815281602082015201906114f1565b33600090815260208190526040902092949392909190613dc7906111c8565b613dd28115156135dd565b613dec61117961117285600052601d602052604060002090565b613dfc6301e1338087111561366b565b613e8f60175496613e0f6111e2896136aa565b613e83613e2689600052601b602052604060002090565b97898955613e61600195613e3c88888d01613b81565b600060028c0155600060038c0155613e5b60048c0160ff198154169055565b42613250565b60058a01556006890180546001600160a01b0319163317905560078901613b81565b84600888015542613250565b94600a8101958655613eae613ea3436131f4565b65ffffffffffff1690565b8061401c5750819060005b600b820155600960009101925b613fc7575b505050613fa5613fc1937fdb17271edb72bcaba16ce918d885db2e701491c9ff3f713f80caf9d614aa9ff4613f957ff46a1614ca62096cf230d10ea203eb985f7a60d98cdffc807d794181bc0a9f9a97957f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd637f5d1231ca3a274bcd2f510e0d53a889213ebf0315b86ee6bb9d73da08fba7460696613f688c613caf565b8b613f7a604051928392339084613d69565b0390a1604080518b8152602081019290925290918291820190565b0390a16040519182918883613d91565b0390a15460408051858152602081019290925290918291820190565b0390a190565b85518110156140175780613ffd613ff8611172613fe7614011958b613c4f565b51600052601d602052604060002090565b613c63565b611fc561400a8289613c4f565b5185613d2d565b81613ec6565b613ecb565b61402590613226565b908291613eb9565b1561403457565b60405162461bcd60e51b815260206004820152601760248201527f50726f706f73616c20646f6573206e6f742065786973740000000000000000006044820152606490fd5b1561408057565b60405162461bcd60e51b815260206004820152600c60248201526b159bdd1a5b99c8195b99195960a21b6044820152606490fd5b156140bb57565b60405162461bcd60e51b815260206004820152601960248201527f50726f706f73616c20616c7265616479206578656375746564000000000000006044820152606490fd5b1561410757565b60405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b6044820152606490fd5b1561414357565b60405162461bcd60e51b815260206004820152601660248201527557726f6e6720636861696e20666f7220766f74696e6760501b6044820152606490fd5b6002600b5414614192576002600b55565b604051633ee5aeb560e01b8152600490fd5b90600a820291808304600a149015171561139257565b8181029291811591840414171561139257565b9081600052601b6020526141e860406000209283541461402d565b60028201546003830154928382019081831161139257600b015460649061421f906001600160d01b03906113509061134b90612a8c565b04111592839182614231575b50509190565b119050388061422b565b1561424257565b606460405162461bcd60e51b815260206004820152602060248201527f45786563757465206f6e6c7920696e20676f7665726e616e636520636861696e6044820152fd5b1561428d57565b60405162461bcd60e51b815260206004820152602760248201527f566f74696e67206e6f7420656e64656420616e642071756f72756d206e6f74206044820152661c995858da195960ca1b6064820152608490fd5b156142e957565b60405162461bcd60e51b8152602060048201526013602482015272141c9bdc1bdcd85b081b9bdd081c185cdcd959606a1b6044820152606490fd5b1561432b57565b60405162461bcd60e51b8152602060048201526014602482015273151a5b595b1bd8dac81b9bdd08195e1c1a5c995960621b6044820152606490fd5b919082526020916040838201526000928254614382816103e3565b9384604085015260019182811690816000146143e457506001146143a9575b505050505090565b6000908152828120949550935b8585106143d05750505060609250010138808080806143a1565b8054858501606001529382019381016143b6565b93505050506060935060ff929192191683830152151560051b010138808080806143a1565b1561441057565b60405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48195e1958dd5d195960821b6044820152606490fd5b1561444f57565b60405162461bcd60e51b815260206004820152600e60248201526d27b7363c9034b734ba34b0ba37b960911b6044820152606490fd5b1561448c57565b60405162461bcd60e51b815260206004820152602360248201527f496e73756666696369656e7420766f74696e6720706f77657220746f2063616e60448201526218d95b60ea1b6064820152608490fd5b91926060938192845260406020850152816040850152848401376000828201840152601f01601f1916010190565b1561451257565b60405162461bcd60e51b815260206004820152602760248201527f50726f706f73616c20616c726561647920657865637574656420696e20746869604482015266399031b430b4b760c91b6064820152608490fd5b1561456e57565b60405162461bcd60e51b815260206004820152602760248201527f557365206578656375746550726f706f73616c20696e20676f7665726e616e63604482015266329031b430b4b760c91b6064820152608490fd5b156145ca57565b60405162461bcd60e51b8152602060048201526014602482015273436861696e206e6f7420696e207461726765747360601b6044820152606490fd5b1561460d57565b60405162461bcd60e51b815260206004820152600e60248201526d426164207369676e61747572657360901b6044820152606490fd5b91908110156114955760051b81013590601e1981360301821215610a995701908135916001600160401b038311610a99576020018236038113610a99579190565b91908110156114955760051b0190565b35610aaf81610bc2565b156146a557565b60405162461bcd60e51b815260206004820152600d60248201526c426164207369676e617475726560981b6044820152606490fd5b156146e157565b60405162461bcd60e51b815260206004820152601060248201526f223ab83634b1b0ba329039b4b3b732b960811b6044820152606490fd5b1561472057565b60405162461bcd60e51b815260206004820152601b60248201527f4e6f20766f74696e6720706f77657220617420736e617073686f7400000000006044820152606490fd5b1561476c57565b60405162461bcd60e51b815260206004820152601a60248201527f51756f72756d206e6f74207265616368656420627920736967730000000000006044820152606490fd5b8151610aaf92612d619260401983016147e9576147e292506020820151906060604084015193015160001a90612d6a565b9192909190565b505060009160029190565b61480d600091808352601b60205260408320541461402d565b80601e54915b82811061482257505050600190565b61484261482e8261485b565b600052601d60205260ff6040600020541690565b1561485557614850906136aa565b614813565b50905090565b601e5481101561487e57601e600052600080516020615efa833981519152015490565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c6d0c2d2dc40d2dcc8caf606b1b6044820152606490fd5b909291926148c68161107f565b916148d460405193846106b7565b829482845282820111610a99576020610713930190610934565b9190604083820312610a995782516001600160e01b031981168103610a9957926020810151906001600160401b038211610a9957019080601f83011215610a99578151610aaf926020016148b9565b90816020910312610a99575190565b9190826040910312610a995760208251920151610aaf81610bc2565b9080601f83011215610a99578151610aaf926020016148b9565b9080601f83011215610a995781519061499a826120c4565b926149a860405194856106b7565b828452602092838086019160051b83010192808411610a9957848301915b8483106149d65750505050505090565b82516001600160401b038111610a995786916149f784848094890101614968565b8152019201916149c6565b91909161010081840312610a99578051916001600160401b0392838111610a995784614a2f918401614968565b936020830151848111610a995781614a48918501614968565b936040840151818111610a995782614a61918601614968565b936060810151828111610a995783614a7a918301614968565b9360808201519360a08301519360c0840151908111610a995760e091614aa1918501614982565b92015190565b614abb6020918280825183010191016148ee565b91906001600160e01b031916630236fce560e51b8103614afa57508181614aeb9261071394518301019101614a02565b96959095949194939293615206565b63f0f9e6b760e01b8103614b2357508181614b1e926107139451830101910161493d565b615304565b632ab43f7f60e11b8103614b4c57508181614b47926107139451830101910161493d565b6153a4565b6304fa45bf60e31b8103614b7f57508181614b70926107139451830101910161494c565b6001600160a01b031690615501565b633972e9fb60e21b8103614ba857508181614ba3926107139451830101910161493d565b6155b1565b63093f734560e31b8103614bd157508181614bcc926107139451830101910161493d565b614c44565b633e78500160e21b8103614bfa57508181614bf5926107139451830101910161493d565b614ddf565b633cdb568760e11b14915061071390505760405162461bcd60e51b81526020600482015260116024820152702ab735b737bbb71037b832b930ba34b7b760791b6044820152606490fd5b80600052601d60205260ff60406000205416614cf2576018548114614cad57614ca881614c9f610cef7fbba9d55e9fd1a441b1617724e2fdb76777d15ec77ab2b72ac15952cbe97085db94600052601d602052604060002090565b6121c581613cf7565b0390a1565b60405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206164642063757272656e7420636861696e00000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f436861696e20616c726561647920737570706f727465640000000000000000006044820152606490fd5b15614d3e57565b60405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742072656d6f76652063757272656e7420636861696e00000000006044820152606490fd5b601e548015614dc95760001981019080821015611495577f50bb669a95c7b50b7e8a6f09454034b2b14cf2b85c730dca9a539ca82cb6e34f600091601e83520155601e55565b634e487b7160e01b600052603160045260246000fd5b614dff60ff614df883600052601d602052604060002090565b5416613629565b614e0d601854821415614d37565b614e2e614e2482600052601d602052604060002090565b805460ff19169055565b60005b601e5480821015614eb55782614e53614e4984611470565b90549060031b1c90565b14614e675750614e62906136aa565b614e31565b91614ead614ca892613d50614ea7614e49614ea27f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d598613226565b611470565b91611470565b6121c5614d83565b5050614ca87f11a9d1a77f76361ed131c19b1dc5758504c51dbde2e49fc973a0ef9577ad13d5916121c5565b15614ee857565b60405162461bcd60e51b815260206004820152601660248201527553796d626f6c2063616e6e6f7420626520656d70747960501b6044820152606490fd5b15614f2d57565b60405162461bcd60e51b815260206004820152601860248201527f4c6f636174696f6e2063616e6e6f7420626520656d70747900000000000000006044820152606490fd5b15614f7957565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b210353ab934b9b234b1ba34b7b760611b6044820152606490fd5b15614fbc57565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964204f4b544d4f60981b6044820152606490fd5b15614ff857565b60405162461bcd60e51b815260206004820152600b60248201526a0496e76616c6964204b50560ac1b6044820152606490fd5b805190600160401b821161066157601254826012558083106150a3575b5060126000526020908101907fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34446000925b848410615087575050505050565b6001838261509783945186613b81565b01920193019290615079565b600060128152837fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344492830192015b8281106150df575050615048565b806150ec600192546103e3565b806150f9575b50016150d1565b601f9081811184146151115750508281555b386150f2565b836151339261512585600052602060002090565b920160051c820191016136b9565b6000818152602081208183555561510b565b9897969495926151889061517a61516a6151969597948d610100908181520190610957565b6020978d89818403910152610957565b908b820360408d0152610957565b9089820360608b0152610957565b93608088015260a087015285830360c08701528151908184528084019381808460051b8301019401946000915b8483106151d857505050505060e09150930152565b909192939484806151f5600193601f198682030187528a51610957565b9801930193019195949392906151c3565b94909591939692968551156152c8577f62d6efdb8dbca656ac38d327c1d66a4ccaeabc91c464fe5e7352b604858f5f4697614ca89561524789511515614ee1565b61525381511515614f26565b61525e831515614f72565b615269841515614fb5565b615274861515614ff1565b61527d88613825565b615286896138fc565b61528f816139d3565b61529882613aaa565b6152a183601055565b6152aa84601155565b6152b38561502b565b6152bc86601355565b60405198899889615145565b60405162461bcd60e51b81526020600482015260146024820152734e616d652063616e6e6f7420626520656d70747960601b6044820152606490fd5b80151580615399575b156153545760168054908290556040805191825260208201929092527fd0198ea88bf9c4ad5317b68e697944e524541fcb494d854f095b1cd88a097ab69181908101614ca8565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642071756f72756d2070657263656e74616765000000000000006044820152606490fd5b50606481111561530d565b80600052601d6020526153be60ff60406000205416613629565b601854908181146154095760188190556040805192835260208301919091527f979103c7afbf0138fe781172504ceb318ff78f9a420de8cabac8141f0121b521919081908101614ca8565b60405162461bcd60e51b815260206004820152600d60248201526c14d85b594818da185a5b881251609a1b6044820152606490fd5b1561544557565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606490fd5b1561548057565b60405162461bcd60e51b81526020600482015260156024820152744d6f64756c6520616c72656164792065786973747360581b6044820152606490fd5b156154c457565b60405162461bcd60e51b8152602060048201526015602482015274135bd91d5b1948191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606490fd5b7ff14475b19484bf096265507cc0c41cd3bf1994992088806830686e2d7272271991906155386001600160a01b038316151561543e565b80600052601a60205261555360ff6040600020541615615479565b600081815260196020526040902080546001600160a01b0319166001600160a01b038416179055601a602090815260406000819020805460ff1916600117905580519283526001600160a01b03909316908201529081908101614ca8565b60207f4c7c76abe482a2c36ea52f1b999474c69f8b4afeeac5635f8aea2526864ba8539180600052601a82526155ee60ff604060002054166154bd565b600081815260198352604080822080546001600160a01b0319169055601a845290819020805460ff1916905551908152a1565b6012549061562e826120c4565b91604061563d815194856106b7565b8184528360208091019160126000527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444906000935b85851061568157505050505050565b600184819284516156968161292b818a610599565b815201930194019391615672565b9060405191828154918282526020928383019160005283600020936000905b8282106156d957505050610713925003836106b7565b8554845260019586019588955093810193909101906156c3565b601c9081549283821015615792578101918282116113925783831161578a575b818303838111611392576157269061300f565b93825b84811061573857505050505090565b81811015611495576157859083600052807f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a211015461577f6157798784613235565b89613c4f565b526136aa565b615729565b839250615713565b50505050610aaf612fe7565b6157b281600052601b602052604060002090565b906157bf8183541461402d565b600482015460ff8160081c1661586e5760ff16615867576157df906141cd565b60058301544210828115948161585f575b81615850575b506158475782918261582e575b5050615827578161581e575b5061581957600090565b600290565b9050153861580f565b5050600190565b8492509061583f575b503880615803565b905038615837565b50505050600590565b600a91500154421015386157f6565b8391506157f0565b5050600390565b505050600490565b9060005b6009830180548210156158b85761589282849261149a565b90549060031b1c146158b0576158a96009916136aa565b905061587a565b505050600190565b50505050600090565b6001600160a01b0390811692918190841561594d575b16908115615905575b6107139360005260086020528060406000205416916000526040600020541690615992565b61590e83615b1a565b93615918436131f4565b6001600160d01b0395868061592b6134ac565b1691169003958611611392576107139561594491615c04565b505093506158e0565b905061595883615b1a565b90615962436131f4565b6001600160d01b039283806159756134ac565b1691160192831161139257839261598b91615c04565b50506158d7565b6001600160a01b03808316939291908116908185141580615adb575b6159ba575b5050505050565b81615a3f575b5050826159cf575b80806159b3565b6001600160a01b031660009081526009602052604090207fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72491615a1c91615a169091615b1a565b90615ae4565b604080516001600160d01b039384168152919092166020820152a23880806159c8565b6001600160a01b03166000908152600960205260409020615a5f84615b1a565b615a68436131f4565b6001600160d01b03918280615a7c866134f6565b169116900392828411611392577fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72493615ad192615ab892615ced565b6040805192851683529316602082015291829190820190565b0390a238806159c0565b508315156159ae565b90615aee436131f4565b6001600160d01b03918280615b02866134f6565b1691160191821161139257615b1692615ced565b9091565b6001600160d01b0390818111615b2e571690565b604490604051906306dfcc6560e41b825260d060048301526024820152fd5b600a5490600160401b821015610661576001820180600a5582101561149557600a600052805160209091015160301b65ffffffffffff191665ffffffffffff9190911617600080516020615eba83398151915290910155565b8054600160401b81101561066157615bc39160018201815561149a565b615bee57815160209092015160301b65ffffffffffff191665ffffffffffff92909216919091179055565b634e487b7160e01b600052600060045260246000fd5b600a549192918015615cc357615c1c615c3491613226565b600a600052600080516020615eba8339815191520190565b9081549165ffffffffffff90818416918316808311615cb157869203615c7957615c7292509065ffffffffffff82549181199060301b169116179055565b60301c9190565b5050615cac90615c98615c8a611072565b65ffffffffffff9092168252565b6001600160d01b0385166020820152615b4d565b615c72565b604051632520601d60e01b8152600490fd5b50615ce790615cd3615c8a611072565b6001600160d01b0384166020820152615b4d565b60009190565b80549293928015615d8457615d04615d1191613226565b8260005260206000200190565b9182549265ffffffffffff91828516928116808411615cb157879303615d505750615c7292509065ffffffffffff82549181199060301b169116179055565b915050615cac91615d70615d62611072565b65ffffffffffff9093168352565b6001600160d01b0386166020830152615ba6565b5090615ce791615d95615d62611072565b6001600160d01b0385166020830152615ba6565b6001600160a01b03808316929181811690848203615e3e57600082815260086020526040902080546001600160a01b031981166001600160a01b038716179091556107139593169392615e389285907f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f600080a46001600160a01b031660009081526020819052604090205490565b91615992565b60405162461bcd60e51b815260206004820152601360248201527211195b1959d85d1a5bdb88191a5cd8589b1959606a1b6044820152606490fdfedf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7bb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fdc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8d7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb550bb669a95c7b50b7e8a6f09454034b2b14cf2b85c730dca9a539ca82cb6e3508d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802a2646970667358221220342bb23de0ffd74d2c73ab1bca80be5afb39937e0bdb34deb68fe801c38061eb64736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/backend/cache/solidity-files-cache.json b/backend/cache/solidity-files-cache.json index cfde2dc..7c07c93 100644 --- a/backend/cache/solidity-files-cache.json +++ b/backend/cache/solidity-files-cache.json @@ -2,8 +2,8 @@ "_format": "hh-sol-cache-2", "files": { "/home/alex/Digital_Legal_Entity(DLE)/backend/contracts/DLE.sol": { - "lastModificationDate": 1754485037554, - "contentHash": "f121cb518877db715ab5cd2e3ee5ff3a", + "lastModificationDate": 1754682456067, + "contentHash": "6d46f24614a8d6c838144dcfad200e26", "sourceName": "contracts/DLE.sol", "solcConfig": { "version": "0.8.20", @@ -32,8 +32,10 @@ }, "imports": [ "@openzeppelin/contracts/token/ERC20/ERC20.sol", + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol", + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol", "@openzeppelin/contracts/utils/ReentrancyGuard.sol", - "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol" + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol" ], "versionPragmas": [ "^0.8.20" @@ -348,6 +350,864 @@ "artifacts": [ "Hashes" ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol": { + "lastModificationDate": 1754306768254, + "contentHash": "b1a8fc63b83ce00408e0c9ed1230b717", + "sourceName": "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "./IERC20Permit.sol", + "../ERC20.sol", + "../../../utils/cryptography/ECDSA.sol", + "../../../utils/cryptography/EIP712.sol", + "../../../utils/Nonces.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "ERC20Permit" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "81de029d56aa803972be03c5d277cb6c", + "sourceName": "@openzeppelin/contracts/utils/cryptography/ECDSA.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "ECDSA" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { + "lastModificationDate": 1754306768254, + "contentHash": "51c2083b160453420aaa0a046c16d5ca", + "sourceName": "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../ERC20.sol", + "../../../governance/utils/Votes.sol", + "../../../utils/structs/Checkpoints.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "ERC20Votes" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/Nonces.sol": { + "lastModificationDate": 1754306760451, + "contentHash": "c32d108058718efb9061b88e83a83f79", + "sourceName": "@openzeppelin/contracts/utils/Nonces.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Nonces" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/cryptography/EIP712.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "8dbb261c55f358342798c4d1803d4f8e", + "sourceName": "@openzeppelin/contracts/utils/cryptography/EIP712.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "./MessageHashUtils.sol", + "../ShortStrings.sol", + "../../interfaces/IERC5267.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "EIP712" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "lastModificationDate": 1754306768254, + "contentHash": "94ec15baf0d5df863f45b8f351937ec7", + "sourceName": "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "IERC20Permit" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/interfaces/IERC5267.sol": { + "lastModificationDate": 1754306760460, + "contentHash": "94364524cb1a39dcbc3d3afff6d8e53e", + "sourceName": "@openzeppelin/contracts/interfaces/IERC5267.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "IERC5267" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/ShortStrings.sol": { + "lastModificationDate": 1754306760451, + "contentHash": "94e7feaf138d08fb736e43ca0be9bf26", + "sourceName": "@openzeppelin/contracts/utils/ShortStrings.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "./StorageSlot.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "ShortStrings" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol": { + "lastModificationDate": 1754306764465, + "contentHash": "86fd93657e4e27ff76c38699e9b9fcef", + "sourceName": "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../Strings.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "MessageHashUtils" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/StorageSlot.sol": { + "lastModificationDate": 1754306760451, + "contentHash": "e656d64c4ce918f3d13030b91c935134", + "sourceName": "@openzeppelin/contracts/utils/StorageSlot.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "StorageSlot" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/Strings.sol": { + "lastModificationDate": 1754306760451, + "contentHash": "a55fef2557b35bac18a1880d3c2e6740", + "sourceName": "@openzeppelin/contracts/utils/Strings.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "./math/Math.sol", + "./math/SafeCast.sol", + "./math/SignedMath.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Strings" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/math/Math.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "2b2665ae9bdb1af440658741a77fe213", + "sourceName": "@openzeppelin/contracts/utils/math/Math.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../Panic.sol", + "./SafeCast.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Math" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "2adca1150f58fc6f3d1f0a0f22ee7cca", + "sourceName": "@openzeppelin/contracts/utils/math/SafeCast.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "SafeCast" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "ae3528afb8bdb0a7dcfba5b115ee8074", + "sourceName": "@openzeppelin/contracts/utils/math/SignedMath.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "./SafeCast.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "SignedMath" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/Panic.sol": { + "lastModificationDate": 1754306760451, + "contentHash": "2133dc13536b4a6a98131e431fac59e1", + "sourceName": "@openzeppelin/contracts/utils/Panic.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Panic" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/governance/utils/Votes.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "95aceafdc639babdd22576e5e3774d64", + "sourceName": "@openzeppelin/contracts/governance/utils/Votes.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../../interfaces/IERC5805.sol", + "../../utils/Context.sol", + "../../utils/Nonces.sol", + "../../utils/cryptography/EIP712.sol", + "../../utils/structs/Checkpoints.sol", + "../../utils/math/SafeCast.sol", + "../../utils/cryptography/ECDSA.sol", + "../../utils/types/Time.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Votes" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/structs/Checkpoints.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "657c6dfea3bae1af948de6113ba01cea", + "sourceName": "@openzeppelin/contracts/utils/structs/Checkpoints.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../math/Math.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Checkpoints" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/interfaces/IERC5805.sol": { + "lastModificationDate": 1754306760460, + "contentHash": "65ba9f89b1057e2192e341b286d4e261", + "sourceName": "@openzeppelin/contracts/interfaces/IERC5805.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../governance/utils/IVotes.sol", + "./IERC6372.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "IERC5805" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/utils/types/Time.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "d83e7814a059fc1287fd765f424ce004", + "sourceName": "@openzeppelin/contracts/utils/types/Time.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [ + "../math/Math.sol", + "../math/SafeCast.sol" + ], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "Time" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { + "lastModificationDate": 1754306764456, + "contentHash": "905ffceb29869fee4b5a649abe7e2927", + "sourceName": "@openzeppelin/contracts/governance/utils/IVotes.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "IVotes" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/node_modules/@openzeppelin/contracts/interfaces/IERC6372.sol": { + "lastModificationDate": 1754306760460, + "contentHash": "414cd6acf090e4009cf016ff62ecbd88", + "sourceName": "@openzeppelin/contracts/interfaces/IERC6372.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "IERC6372" + ] + }, + "/home/alex/Digital_Legal_Entity(DLE)/backend/contracts/FactoryDeployer.sol": { + "lastModificationDate": 1754683537642, + "contentHash": "6161bbb21af830bc05d6acd8682d9678", + "sourceName": "contracts/FactoryDeployer.sol", + "solcConfig": { + "version": "0.8.20", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "viaIR": true, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } + }, + "imports": [], + "versionPragmas": [ + "^0.8.20" + ], + "artifacts": [ + "FactoryDeployer" + ] } } } diff --git a/backend/contracts/DLE.sol b/backend/contracts/DLE.sol index e8e1daa..5a91b98 100644 --- a/backend/contracts/DLE.sol +++ b/backend/contracts/DLE.sol @@ -11,14 +11,18 @@ pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; -import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; /** * @title DLE (Digital Legal Entity) - * @dev Основной контракт DLE с модульной архитектурой и мульти-чейн поддержкой + * @dev Основной контракт DLE с модульной архитектурой, Single-Chain Governance + * и безопасной мульти-чейн синхронизацией без сторонних мостов (через подписи холдеров). */ -contract DLE is ERC20, ReentrancyGuard { +contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard { + using ECDSA for bytes32; struct DLEInfo { string name; string symbol; @@ -53,11 +57,15 @@ contract DLE is ERC20, ReentrancyGuard { uint256 forVotes; uint256 againstVotes; bool executed; - uint256 deadline; + bool canceled; + uint256 deadline; // конец периода голосования (sec) address initiator; - bytes operation; // Операция для исполнения + bytes operation; // операция для исполнения + uint256 governanceChainId; // сеть голосования (Single-Chain Governance) + uint256[] targetChains; // целевые сети для исполнения + uint256 timelock; // earliest execution timestamp (sec) + uint256 snapshotTimepoint; // блок/временная точка для getPastVotes mapping(address => bool) hasVoted; - mapping(uint256 => bool) chainVoteSynced; // Синхронизация голосов между цепочками } @@ -74,15 +82,11 @@ contract DLE is ERC20, ReentrancyGuard { // Предложения mapping(uint256 => Proposal) public proposals; + uint256[] public allProposalIds; // Мульти-чейн mapping(uint256 => bool) public supportedChains; uint256[] public supportedChainIds; - mapping(uint256 => bool) public executedProposals; // Синхронизация исполненных предложений - - // Merkle proofs для cross-chain синхронизации - mapping(uint256 => bytes32) public chainMerkleRoots; // chainId => merkleRoot - mapping(uint256 => mapping(uint256 => bool)) public processedProofs; // proposalId => proofHash => processed // События event DLEInitialized( @@ -101,21 +105,29 @@ contract DLE is ERC20, ReentrancyGuard { event ProposalCreated(uint256 proposalId, address initiator, string description); event ProposalVoted(uint256 proposalId, address voter, bool support, uint256 votingPower); event ProposalExecuted(uint256 proposalId, bytes operation); + event ProposalCancelled(uint256 proposalId, string reason); + event ProposalTimelockSet(uint256 proposalId, uint256 timelock); + event ProposalTargetsSet(uint256 proposalId, uint256[] targetChains); + event ProposalGovernanceChainSet(uint256 proposalId, uint256 governanceChainId); event ModuleAdded(bytes32 moduleId, address moduleAddress); event ModuleRemoved(bytes32 moduleId); - event CrossChainExecutionSync(uint256 proposalId, uint256 fromChainId, uint256 toChainId); - event CrossChainVoteSync(uint256 proposalId, uint256 fromChainId, uint256 toChainId); + event ProposalExecutionApprovedInChain(uint256 proposalId, uint256 chainId); event ChainAdded(uint256 chainId); event ChainRemoved(uint256 chainId); - event ChainMerkleRootSet(uint256 chainId, bytes32 merkleRoot); event DLEInfoUpdated(string name, string symbol, string location, string coordinates, uint256 jurisdiction, uint256 oktmo, string[] okvedCodes, uint256 kpp); event QuorumPercentageUpdated(uint256 oldQuorumPercentage, uint256 newQuorumPercentage); event CurrentChainIdUpdated(uint256 oldChainId, uint256 newChainId); + // EIP712 typehash для подписи одобрения исполнения предложения в целевой сети + // ExecutionApproval(uint256 proposalId, bytes32 operationHash, uint256 chainId, uint256 snapshotTimepoint) + bytes32 private constant EXECUTION_APPROVAL_TYPEHASH = keccak256( + "ExecutionApproval(uint256 proposalId,bytes32 operationHash,uint256 chainId,uint256 snapshotTimepoint)" + ); + constructor( DLEConfig memory config, uint256 _currentChainId - ) ERC20(config.name, config.symbol) { + ) ERC20(config.name, config.symbol) ERC20Permit(config.name) { dleInfo = DLEInfo({ name: config.name, symbol: config.symbol, @@ -143,9 +155,13 @@ contract DLE is ERC20, ReentrancyGuard { require(config.initialPartners.length > 0, "No initial partners"); for (uint256 i = 0; i < config.initialPartners.length; i++) { - require(config.initialPartners[i] != address(0), "Zero address"); - require(config.initialAmounts[i] > 0, "Zero amount"); - _mint(config.initialPartners[i], config.initialAmounts[i]); + address partner = config.initialPartners[i]; + uint256 amount = config.initialAmounts[i]; + require(partner != address(0), "Zero address"); + require(amount > 0, "Zero amount"); + _mint(partner, amount); + // Авто-делегирование голосов себе, чтобы getPastVotes работал без действия пользователя + _delegate(partner, partner); } emit InitialTokensDistributed(config.initialPartners, config.initialAmounts); @@ -174,12 +190,14 @@ contract DLE is ERC20, ReentrancyGuard { string memory _description, uint256 _duration, bytes memory _operation, - uint256 _governanceChainId + uint256 _governanceChainId, + uint256[] memory _targetChains, + uint256 _timelockDelay ) external returns (uint256) { require(balanceOf(msg.sender) > 0, "Must hold tokens to create proposal"); require(_duration > 0, "Duration must be positive"); require(supportedChains[_governanceChainId], "Chain not supported"); - require(checkChainConnection(_governanceChainId), "Chain not available"); + require(_timelockDelay <= 365 days, "Timelock too big"); uint256 proposalId = proposalCounter++; Proposal storage proposal = proposals[proposalId]; @@ -192,8 +210,22 @@ contract DLE is ERC20, ReentrancyGuard { proposal.deadline = block.timestamp + _duration; proposal.initiator = msg.sender; proposal.operation = _operation; + proposal.governanceChainId = _governanceChainId; + proposal.timelock = block.timestamp + _timelockDelay; + // Снимок голосов: используем прошлую точку времени, чтобы getPastVotes был валиден в текущем блоке + uint256 nowClock = clock(); + proposal.snapshotTimepoint = nowClock == 0 ? 0 : nowClock - 1; + // запись целевых сетей + for (uint256 i = 0; i < _targetChains.length; i++) { + require(supportedChains[_targetChains[i]], "Target chain not supported"); + proposal.targetChains.push(_targetChains[i]); + } + allProposalIds.push(proposalId); emit ProposalCreated(proposalId, msg.sender, _description); + emit ProposalGovernanceChainSet(proposalId, _governanceChainId); + emit ProposalTargetsSet(proposalId, _targetChains); + emit ProposalTimelockSet(proposalId, proposal.timelock); return proposalId; } @@ -208,9 +240,10 @@ contract DLE is ERC20, ReentrancyGuard { require(block.timestamp < proposal.deadline, "Voting ended"); require(!proposal.executed, "Proposal already executed"); require(!proposal.hasVoted[msg.sender], "Already voted"); - require(balanceOf(msg.sender) > 0, "No tokens to vote"); + require(currentChainId == proposal.governanceChainId, "Wrong chain for voting"); - uint256 votingPower = balanceOf(msg.sender); + // используем снапшот голосов для защиты от перелива + uint256 votingPower = getPastVotes(msg.sender, proposal.snapshotTimepoint); proposal.hasVoted[msg.sender] = true; if (_support) { @@ -222,53 +255,7 @@ contract DLE is ERC20, ReentrancyGuard { emit ProposalVoted(_proposalId, msg.sender, _support, votingPower); } - /** - * @dev Синхронизировать голос из другой цепочки - * @param _proposalId ID предложения - * @param _fromChainId ID цепочки откуда синхронизируем - * @param _forVotes Голоса за - * @param _againstVotes Голоса против - */ - function syncVoteFromChain( - uint256 _proposalId, - uint256 _fromChainId, - uint256 _forVotes, - uint256 _againstVotes, - bytes memory _proof - ) external { - Proposal storage proposal = proposals[_proposalId]; - require(proposal.id == _proposalId, "Proposal does not exist"); - require(supportedChains[_fromChainId], "Chain not supported"); - require(!proposal.chainVoteSynced[_fromChainId], "Already synced"); - - // Проверяем доказательство cross-chain синхронизации - require(_proof.length > 0, "Proof required for cross-chain sync"); - - // Проверяем Merkle proof для cross-chain синхронизации - bytes32 proofHash = keccak256(abi.encodePacked(_proposalId, _fromChainId, _forVotes, _againstVotes)); - require(!processedProofs[_proposalId][uint256(proofHash)], "Proof already processed"); - - // Проверяем, что Merkle root для цепочки установлен - bytes32 merkleRoot = chainMerkleRoots[_fromChainId]; - require(merkleRoot != bytes32(0), "Merkle root not set for chain"); - - // Проверяем Merkle proof - bytes32[] memory proof = abi.decode(_proof, (bytes32[])); - require(MerkleProof.verify(proof, merkleRoot, proofHash), "Invalid Merkle proof"); - - // Отмечаем proof как обработанный - processedProofs[_proposalId][uint256(proofHash)] = true; - - // Проверяем, что голоса не превышают общее количество токенов - uint256 totalVotes = _forVotes + _againstVotes; - require(totalVotes <= totalSupply(), "Votes exceed total supply"); - - proposal.forVotes += _forVotes; - proposal.againstVotes += _againstVotes; - proposal.chainVoteSynced[_fromChainId] = true; - - emit CrossChainVoteSync(_proposalId, _fromChainId, currentChainId); - } + // УДАЛЕНО: syncVoteFromChain с MerkleProof — небезопасно без доверенного моста /** * @dev Проверить результат предложения @@ -281,7 +268,9 @@ contract DLE is ERC20, ReentrancyGuard { require(proposal.id == _proposalId, "Proposal does not exist"); uint256 totalVotes = proposal.forVotes + proposal.againstVotes; - uint256 quorumRequired = (totalSupply() * quorumPercentage) / 100; + // Используем снапшот totalSupply на момент начала голосования + uint256 pastSupply = getPastTotalSupply(proposal.snapshotTimepoint); + uint256 quorumRequired = (pastSupply * quorumPercentage) / 100; quorumReached = totalVotes >= quorumRequired; passed = quorumReached && proposal.forVotes > proposal.againstVotes; @@ -297,6 +286,7 @@ contract DLE is ERC20, ReentrancyGuard { Proposal storage proposal = proposals[_proposalId]; require(proposal.id == _proposalId, "Proposal does not exist"); require(!proposal.executed, "Proposal already executed"); + require(currentChainId == proposal.governanceChainId, "Execute only in governance chain"); (bool passed, bool quorumReached) = checkProposalResult(_proposalId); @@ -307,6 +297,7 @@ contract DLE is ERC20, ReentrancyGuard { "Voting not ended and quorum not reached" ); require(passed && quorumReached, "Proposal not passed"); + require(block.timestamp >= proposal.timelock, "Timelock not expired"); proposal.executed = true; @@ -317,49 +308,74 @@ contract DLE is ERC20, ReentrancyGuard { } /** - * @dev Синхронизировать исполнение из другой цепочки - * @param _proposalId ID предложения - * @param _fromChainId ID цепочки откуда синхронизируем + * @dev Отмена предложения до истечения голосования инициатором при наличии достаточной голосующей силы. + * Это soft-cancel для защиты от явных ошибок. Порог: >= 10% от снапшотного supply. */ - function syncExecutionFromChain( - uint256 _proposalId, - uint256 _fromChainId, - bytes memory _proof - ) external { - require(supportedChains[_fromChainId], "Chain not supported"); - require(!executedProposals[_proposalId], "Already executed"); + function cancelProposal(uint256 _proposalId, string calldata reason) external { + Proposal storage proposal = proposals[_proposalId]; + require(proposal.id == _proposalId, "Proposal does not exist"); + require(!proposal.executed, "Already executed"); + require(block.timestamp < proposal.deadline, "Voting ended"); + require(msg.sender == proposal.initiator, "Only initiator"); + uint256 vp = getPastVotes(msg.sender, proposal.snapshotTimepoint); + uint256 pastSupply = getPastTotalSupply(proposal.snapshotTimepoint); + require(vp * 10 >= pastSupply, "Insufficient voting power to cancel"); - // Проверяем доказательство исполнения из другой цепочки - require(_proof.length > 0, "Proof required for cross-chain execution"); - - // Проверяем Merkle proof для cross-chain исполнения - bytes32 proofHash = keccak256(abi.encodePacked(_proposalId, _fromChainId, "EXECUTION")); - require(!processedProofs[_proposalId][uint256(proofHash)], "Proof already processed"); - - // Проверяем, что Merkle root для цепочки установлен - bytes32 merkleRoot = chainMerkleRoots[_fromChainId]; - require(merkleRoot != bytes32(0), "Merkle root not set for chain"); - - // Проверяем Merkle proof - bytes32[] memory proof = abi.decode(_proof, (bytes32[])); - require(MerkleProof.verify(proof, merkleRoot, proofHash), "Invalid Merkle proof"); - - // Отмечаем proof как обработанный - processedProofs[_proposalId][uint256(proofHash)] = true; - - // Проверяем, что предложение существует и не было исполнено + proposal.canceled = true; + emit ProposalCancelled(_proposalId, reason); + } + + // УДАЛЕНО: syncExecutionFromChain с MerkleProof — небезопасно без доверенного моста + + /** + * @dev Исполнение предложения в НЕ governance-сети по подписям холдеров на снапшоте. + * Подходит для target chains. Не требует внешнего моста. + */ + function executeProposalBySignatures( + uint256 _proposalId, + address[] calldata signers, + bytes[] calldata signatures + ) external nonReentrant { Proposal storage proposal = proposals[_proposalId]; require(proposal.id == _proposalId, "Proposal does not exist"); - require(!proposal.executed, "Proposal already executed"); + require(!proposal.executed, "Proposal already executed in this chain"); + require(currentChainId != proposal.governanceChainId, "Use executeProposal in governance chain"); + require(_isTargetChain(proposal, currentChainId), "Chain not in targets"); + require(block.timestamp >= proposal.timelock, "Timelock not expired"); - executedProposals[_proposalId] = true; - - // Исполняем операцию из предложения - if (proposal.id == _proposalId) { - _executeOperation(proposal.operation); + require(signers.length == signatures.length, "Bad signatures"); + bytes32 opHash = keccak256(proposal.operation); + bytes32 structHash = keccak256(abi.encode( + EXECUTION_APPROVAL_TYPEHASH, + _proposalId, + opHash, + currentChainId, + proposal.snapshotTimepoint + )); + bytes32 digest = _hashTypedDataV4(structHash); + + uint256 votesFor = 0; + // простая защита от дублей адресов (O(n^2) по малому n) + for (uint256 i = 0; i < signers.length; i++) { + address recovered = ECDSA.recover(digest, signatures[i]); + require(recovered == signers[i], "Bad signature"); + // проверка на дубли + for (uint256 j = 0; j < i; j++) { + require(signers[j] != recovered, "Duplicate signer"); + } + uint256 vp = getPastVotes(recovered, proposal.snapshotTimepoint); + require(vp > 0, "No voting power at snapshot"); + votesFor += vp; } - emit CrossChainExecutionSync(_proposalId, _fromChainId, currentChainId); + uint256 pastSupply = getPastTotalSupply(proposal.snapshotTimepoint); + uint256 quorumRequired = (pastSupply * quorumPercentage) / 100; + require(votesFor >= quorumRequired, "Quorum not reached by sigs"); + + proposal.executed = true; + _executeOperation(proposal.operation); + emit ProposalExecuted(_proposalId, proposal.operation); + emit ProposalExecutionApprovedInChain(_proposalId, currentChainId); } /** @@ -368,19 +384,8 @@ contract DLE is ERC20, ReentrancyGuard { * @return isAvailable Доступна ли цепочка */ function checkChainConnection(uint256 _chainId) public view returns (bool isAvailable) { - // Проверяем, поддерживается ли цепочка - if (!supportedChains[_chainId]) { - return false; - } - - // Проверяем, что Merkle root установлен для цепочки - // Это означает, что цепочка активна и готова к синхронизации - bytes32 merkleRoot = chainMerkleRoots[_chainId]; - if (merkleRoot == bytes32(0)) { - return false; - } - - return true; + // Упрощенная проверка: цепочка объявлена как поддерживаемая + return supportedChains[_chainId]; } /** @@ -410,12 +415,8 @@ contract DLE is ERC20, ReentrancyGuard { function syncToAllChains(uint256 _proposalId) external { require(checkSyncReadiness(_proposalId), "Not all chains ready"); - // Выполняем синхронизацию во все цепочки - for (uint256 i = 0; i < getSupportedChainCount(); i++) { - uint256 chainId = getSupportedChainId(i); - syncToChain(_proposalId, chainId); - } - + // В этой версии без внешнего моста синхронизация выполняется + // через executeProposalBySignatures в целевых сетях. emit SyncCompleted(_proposalId); } @@ -424,26 +425,7 @@ contract DLE is ERC20, ReentrancyGuard { * @param _proposalId ID предложения * @param _chainId ID цепочки */ - function syncToChain(uint256 _proposalId, uint256 _chainId) internal { - // Проверяем, что цепочка поддерживается - require(supportedChains[_chainId], "Chain not supported"); - - // Получаем информацию о предложении - Proposal storage proposal = proposals[_proposalId]; - require(proposal.id == _proposalId, "Proposal does not exist"); - - // Проверяем, что цепочка готова к синхронизации - require(checkChainConnection(_chainId), "Chain not ready for sync"); - - // Создаем Merkle root для синхронизации - bytes32 syncData = keccak256(abi.encodePacked(_proposalId, currentChainId, proposal.operation)); - - // Обновляем Merkle root для целевой цепочки - chainMerkleRoots[_chainId] = syncData; - - // Эмитим событие для cross-chain bridge - emit CrossChainExecutionSync(_proposalId, currentChainId, _chainId); - } + // УДАЛЕНО: syncToChain — не используется в подпись‑ориентированной схеме /** * @dev Получить количество поддерживаемых цепочек @@ -465,14 +447,12 @@ contract DLE is ERC20, ReentrancyGuard { * @dev Добавить поддерживаемую цепочку (только для владельцев токенов) * @param _chainId ID цепочки */ - function addSupportedChain(uint256 _chainId) external { - require(balanceOf(msg.sender) > 0, "Must hold tokens to add chain"); + // Управление списком сетей теперь выполняется только через предложения + function _addSupportedChain(uint256 _chainId) internal { require(!supportedChains[_chainId], "Chain already supported"); require(_chainId != currentChainId, "Cannot add current chain"); - supportedChains[_chainId] = true; supportedChainIds.push(_chainId); - emit ChainAdded(_chainId); } @@ -480,13 +460,10 @@ contract DLE is ERC20, ReentrancyGuard { * @dev Удалить поддерживаемую цепочку (только для владельцев токенов) * @param _chainId ID цепочки */ - function removeSupportedChain(uint256 _chainId) external { - require(balanceOf(msg.sender) > 0, "Must hold tokens to remove chain"); + function _removeSupportedChain(uint256 _chainId) internal { require(supportedChains[_chainId], "Chain not supported"); require(_chainId != currentChainId, "Cannot remove current chain"); - supportedChains[_chainId] = false; - // Удаляем из массива for (uint256 i = 0; i < supportedChainIds.length; i++) { if (supportedChainIds[i] == _chainId) { @@ -495,10 +472,6 @@ contract DLE is ERC20, ReentrancyGuard { break; } } - - // Очищаем Merkle root для цепочки - delete chainMerkleRoots[_chainId]; - emit ChainRemoved(_chainId); } @@ -507,22 +480,13 @@ contract DLE is ERC20, ReentrancyGuard { * @param _chainId ID цепочки * @param _merkleRoot Merkle root для цепочки */ - function setChainMerkleRoot(uint256 _chainId, bytes32 _merkleRoot) external { - require(balanceOf(msg.sender) > 0, "Must hold tokens to set merkle root"); - require(supportedChains[_chainId], "Chain not supported"); - - chainMerkleRoots[_chainId] = _merkleRoot; - - emit ChainMerkleRootSet(_chainId, _merkleRoot); - } + // УДАЛЕНО: setChainMerkleRoot — небезопасно отдавать любому холдеру /** * @dev Получить Merkle root для цепочки * @param _chainId ID цепочки */ - function getChainMerkleRoot(uint256 _chainId) external view returns (bytes32) { - return chainMerkleRoots[_chainId]; - } + // УДАЛЕНО: getChainMerkleRoot — устарело /** * @dev Исполнить операцию @@ -532,19 +496,7 @@ contract DLE is ERC20, ReentrancyGuard { // Декодируем операцию (bytes4 selector, bytes memory data) = abi.decode(_operation, (bytes4, bytes)); - if (selector == bytes4(keccak256("transfer(address,uint256)"))) { - // Операция передачи токенов - (address to, uint256 amount) = abi.decode(data, (address, uint256)); - _transfer(msg.sender, to, amount); - } else if (selector == bytes4(keccak256("mint(address,uint256)"))) { - // Операция минтинга токенов - (address to, uint256 amount) = abi.decode(data, (address, uint256)); - _mint(to, amount); - } else if (selector == bytes4(keccak256("burn(address,uint256)"))) { - // Операция сжигания токенов - (address from, uint256 amount) = abi.decode(data, (address, uint256)); - _burn(from, amount); - } else if (selector == bytes4(keccak256("updateDLEInfo(string,string,string,string,uint256,uint256,string[],uint256)"))) { + if (selector == bytes4(keccak256("updateDLEInfo(string,string,string,string,uint256,uint256,string[],uint256)"))) { // Операция обновления информации DLE (string memory name, string memory symbol, string memory location, string memory coordinates, uint256 jurisdiction, uint256 oktmo, string[] memory okvedCodes, uint256 kpp) = abi.decode(data, (string, string, string, string, uint256, uint256, string[], uint256)); @@ -565,6 +517,16 @@ contract DLE is ERC20, ReentrancyGuard { // Операция удаления модуля (bytes32 moduleId) = abi.decode(data, (bytes32)); _removeModule(moduleId); + } else if (selector == bytes4(keccak256("_addSupportedChain(uint256)"))) { + (uint256 chainIdToAdd) = abi.decode(data, (uint256)); + _addSupportedChain(chainIdToAdd); + } else if (selector == bytes4(keccak256("_removeSupportedChain(uint256)"))) { + (uint256 chainIdToRemove) = abi.decode(data, (uint256)); + _removeSupportedChain(chainIdToRemove); + } else if (selector == bytes4(keccak256("offchainAction(bytes32,string,bytes32)"))) { + // Оффчейн операция для приложения: идентификатор, тип, хеш полезной нагрузки + // (bytes32 actionId, string memory kind, bytes32 payloadHash) = abi.decode(data, (bytes32, string, bytes32)); + // Ончейн-побочных эффектов нет. Факт решения фиксируется событием ProposalExecuted. } else { // Неизвестная операция revert("Unknown operation"); @@ -654,7 +616,6 @@ contract DLE is ERC20, ReentrancyGuard { uint256 _chainId ) external returns (uint256) { require(supportedChains[_chainId], "Chain not supported"); - require(checkChainConnection(_chainId), "Chain not available"); require(_moduleAddress != address(0), "Zero address"); require(!activeModules[_moduleId], "Module already exists"); require(balanceOf(msg.sender) > 0, "Must hold tokens to create proposal"); @@ -693,7 +654,6 @@ contract DLE is ERC20, ReentrancyGuard { uint256 _chainId ) external returns (uint256) { require(supportedChains[_chainId], "Chain not supported"); - require(checkChainConnection(_chainId), "Chain not available"); require(activeModules[_moduleId], "Module does not exist"); require(balanceOf(msg.sender) > 0, "Must hold tokens to create proposal"); @@ -782,192 +742,146 @@ contract DLE is ERC20, ReentrancyGuard { return currentChainId; } - // События для новых функций - event SyncCompleted(uint256 proposalId); - event DLEDeactivated(address indexed deactivatedBy, uint256 timestamp); - event DeactivationProposalCreated(uint256 proposalId, address indexed initiator, string description); - event DeactivationProposalVoted(uint256 proposalId, address indexed voter, bool support, uint256 votingPower); - event DeactivationProposalExecuted(uint256 proposalId, address indexed executedBy); - - // Структура для предложения деактивации - struct DeactivationProposal { - uint256 id; - string description; - uint256 forVotes; - uint256 againstVotes; - bool executed; - uint256 deadline; - address initiator; - uint256 chainId; - mapping(address => bool) hasVoted; - } - - // Предложения деактивации - mapping(uint256 => DeactivationProposal) public deactivationProposals; - uint256 public deactivationProposalCounter; - bool public isDeactivated; - - /** - * @dev Создать предложение о деактивации DLE - * @param _description Описание предложения - * @param _duration Длительность голосования в секундах - * @param _chainId ID цепочки для деактивации - */ - function createDeactivationProposal( - string memory _description, - uint256 _duration, - uint256 _chainId - ) external returns (uint256) { - require(!isDeactivated, "DLE already deactivated"); - require(balanceOf(msg.sender) > 0, "Must hold tokens to create deactivation proposal"); - require(_duration > 0, "Duration must be positive"); - require(supportedChains[_chainId], "Chain not supported"); - - uint256 proposalId = deactivationProposalCounter++; - DeactivationProposal storage proposal = deactivationProposals[proposalId]; - - proposal.id = proposalId; - proposal.description = _description; - proposal.forVotes = 0; - proposal.againstVotes = 0; - proposal.executed = false; - proposal.deadline = block.timestamp + _duration; - proposal.initiator = msg.sender; - proposal.chainId = _chainId; - - emit DeactivationProposalCreated(proposalId, msg.sender, _description); - return proposalId; - } - - /** - * @dev Голосовать за предложение деактивации - * @param _proposalId ID предложения - * @param _support Поддержка предложения - */ - function voteDeactivation(uint256 _proposalId, bool _support) external nonReentrant { - DeactivationProposal storage proposal = deactivationProposals[_proposalId]; - require(proposal.id == _proposalId, "Deactivation proposal does not exist"); - require(block.timestamp < proposal.deadline, "Voting ended"); - require(!proposal.executed, "Proposal already executed"); - require(!proposal.hasVoted[msg.sender], "Already voted"); - require(balanceOf(msg.sender) > 0, "No tokens to vote"); - - uint256 votingPower = balanceOf(msg.sender); - - if (_support) { - proposal.forVotes += votingPower; - } else { - proposal.againstVotes += votingPower; - } - - proposal.hasVoted[msg.sender] = true; - - emit DeactivationProposalVoted(_proposalId, msg.sender, _support, votingPower); - } - - /** - * @dev Проверить результат предложения деактивации - * @param _proposalId ID предложения - */ - function checkDeactivationProposalResult(uint256 _proposalId) public view returns (bool passed, bool quorumReached) { - DeactivationProposal storage proposal = deactivationProposals[_proposalId]; - require(proposal.id == _proposalId, "Deactivation proposal does not exist"); - - uint256 totalVotes = proposal.forVotes + proposal.againstVotes; - uint256 totalSupply = totalSupply(); - - quorumReached = totalVotes >= (totalSupply * quorumPercentage) / 100; - passed = quorumReached && proposal.forVotes > proposal.againstVotes; - - return (passed, quorumReached); - } - - /** - * @dev Исполнить предложение деактивации - * @param _proposalId ID предложения - */ - function executeDeactivationProposal(uint256 _proposalId) external { - DeactivationProposal storage proposal = deactivationProposals[_proposalId]; - require(proposal.id == _proposalId, "Deactivation proposal does not exist"); - require(!proposal.executed, "Proposal already executed"); - require(block.timestamp >= proposal.deadline, "Voting not ended"); - - (bool passed, bool quorumReached) = checkDeactivationProposalResult(_proposalId); - require(quorumReached, "Quorum not reached"); - require(passed, "Proposal not passed"); - - proposal.executed = true; - isDeactivated = true; - dleInfo.isActive = false; - - emit DeactivationProposalExecuted(_proposalId, msg.sender); - emit DLEDeactivated(msg.sender, block.timestamp); - } - - /** - * @dev Деактивировать DLE напрямую (только при достижении кворума) - * Может быть вызвана только если есть активное предложение деактивации с достигнутым кворумом - */ - function deactivate() external { - require(!isDeactivated, "DLE already deactivated"); - require(balanceOf(msg.sender) > 0, "Must hold tokens to deactivate DLE"); - - // Проверяем, есть ли активное предложение деактивации с достигнутым кворумом - bool hasValidDeactivationProposal = false; - - for (uint256 i = 0; i < deactivationProposalCounter; i++) { - DeactivationProposal storage proposal = deactivationProposals[i]; - if (!proposal.executed && block.timestamp >= proposal.deadline) { - (bool passed, bool quorumReached) = checkDeactivationProposalResult(i); - if (quorumReached && passed) { - hasValidDeactivationProposal = true; - proposal.executed = true; - break; - } - } - } - - require(hasValidDeactivationProposal, "No valid deactivation proposal with quorum"); - - isDeactivated = true; - dleInfo.isActive = false; - - emit DLEDeactivated(msg.sender, block.timestamp); - } - - /** - * @dev Проверить, деактивирован ли DLE - */ - function isActive() external view returns (bool) { - return !isDeactivated && dleInfo.isActive; - } - - /** - * @dev Получить информацию о предложении деактивации - * @param _proposalId ID предложения - */ - function getDeactivationProposal(uint256 _proposalId) external view returns ( + // ===== Интерфейс аналитики для API ===== + function getProposalSummary(uint256 _proposalId) external view returns ( uint256 id, string memory description, uint256 forVotes, uint256 againstVotes, bool executed, + bool canceled, uint256 deadline, address initiator, - uint256 chainId + uint256 governanceChainId, + uint256 timelock, + uint256 snapshotTimepoint, + uint256[] memory targets ) { - DeactivationProposal storage proposal = deactivationProposals[_proposalId]; - require(proposal.id == _proposalId, "Deactivation proposal does not exist"); - + Proposal storage p = proposals[_proposalId]; + require(p.id == _proposalId, "Proposal does not exist"); return ( - proposal.id, - proposal.description, - proposal.forVotes, - proposal.againstVotes, - proposal.executed, - proposal.deadline, - proposal.initiator, - proposal.chainId + p.id, + p.description, + p.forVotes, + p.againstVotes, + p.executed, + p.canceled, + p.deadline, + p.initiator, + p.governanceChainId, + p.timelock, + p.snapshotTimepoint, + p.targetChains ); } -} \ No newline at end of file + + function getGovernanceParams() external view returns ( + uint256 quorumPct, + uint256 chainId, + uint256 supportedCount + ) { + return (quorumPercentage, currentChainId, supportedChainIds.length); + } + + function listSupportedChains() external view returns (uint256[] memory) { + return supportedChainIds; + } + + function getVotingPowerAt(address voter, uint256 timepoint) external view returns (uint256) { + return getPastVotes(voter, timepoint); + } + + // ===== Пагинация и агрегирование ===== + function getProposalsCount() external view returns (uint256) { + return allProposalIds.length; + } + + function listProposals(uint256 offset, uint256 limit) external view returns (uint256[] memory) { + uint256 total = allProposalIds.length; + if (offset >= total) { + return new uint256[](0); + } + uint256 end = offset + limit; + if (end > total) end = total; + uint256[] memory page = new uint256[](end - offset); + for (uint256 i = offset; i < end; i++) { + page[i - offset] = allProposalIds[i]; + } + return page; + } + + // 0=Pending, 1=Succeeded, 2=Defeated, 3=Executed, 4=Canceled, 5=ReadyForExecution + function getProposalState(uint256 _proposalId) public view returns (uint8 state) { + Proposal storage p = proposals[_proposalId]; + require(p.id == _proposalId, "Proposal does not exist"); + if (p.canceled) return 4; + if (p.executed) return 3; + (bool passed, bool quorumReached) = checkProposalResult(_proposalId); + bool votingOver = block.timestamp >= p.deadline; + bool ready = passed && quorumReached && block.timestamp >= p.timelock; + if (ready) return 5; // ReadyForExecution + if (passed && (votingOver || quorumReached)) return 1; // Succeeded + if (votingOver && !passed) return 2; // Defeated + return 0; // Pending + } + + function getQuorumAt(uint256 timepoint) external view returns (uint256) { + uint256 supply = getPastTotalSupply(timepoint); + return (supply * quorumPercentage) / 100; + } + + function getProposalVotes(uint256 _proposalId) external view returns ( + uint256 forVotes, + uint256 againstVotes, + uint256 totalVotes, + uint256 quorumRequired + ) { + Proposal storage p = proposals[_proposalId]; + require(p.id == _proposalId, "Proposal does not exist"); + uint256 supply = getPastTotalSupply(p.snapshotTimepoint); + uint256 quorumReq = (supply * quorumPercentage) / 100; + return (p.forVotes, p.againstVotes, p.forVotes + p.againstVotes, quorumReq); + } + + // События для новых функций + event SyncCompleted(uint256 proposalId); + event DLEDeactivated(address indexed deactivatedBy, uint256 timestamp); + + bool public isDeactivated; + + // Деактивация вынесена в отдельный модуль. См. DeactivationModule. + function isActive() external view returns (bool) { + return !isDeactivated && dleInfo.isActive; + } + // ===== Вспомогательные функции ===== + function _isTargetChain(Proposal storage p, uint256 chainId) internal view returns (bool) { + for (uint256 i = 0; i < p.targetChains.length; i++) { + if (p.targetChains[i] == chainId) return true; + } + return false; + } + + // ===== Overrides для ERC20Votes ===== + function _update(address from, address to, uint256 value) + internal + override(ERC20, ERC20Votes) + { + super._update(from, to, value); + } + + // Разрешаем неоднозначность nonces из базовых классов + function nonces(address owner) + public + view + override(ERC20Permit, Nonces) + returns (uint256) + { + return super.nonces(owner); + } + + // Запрет делегирования на третьих лиц: разрешено только делегировать самому себе + function _delegate(address delegator, address delegatee) internal override { + require(delegator == delegatee, "Delegation disabled"); + super._delegate(delegator, delegatee); + } +} diff --git a/backend/contracts/FactoryDeployer.sol b/backend/contracts/FactoryDeployer.sol new file mode 100644 index 0000000..31b6d14 --- /dev/null +++ b/backend/contracts/FactoryDeployer.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract FactoryDeployer { + event Deployed(address addr, bytes32 salt); + + function deploy(bytes32 salt, bytes memory creationCode) external payable returns (address addr) { + require(creationCode.length != 0, "init code empty"); + // solhint-disable-next-line no-inline-assembly + assembly { + addr := create2(callvalue(), add(creationCode, 0x20), mload(creationCode), salt) + } + require(addr != address(0), "CREATE2 failed"); + emit Deployed(addr, salt); + } + + function computeAddress(bytes32 salt, bytes32 initCodeHash) external view returns (address) { + bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, initCodeHash)); + return address(uint160(uint256(hash))); + } +} + + diff --git a/backend/routes/dleV2.js b/backend/routes/dleV2.js index d1aa4f1..dead433 100644 --- a/backend/routes/dleV2.js +++ b/backend/routes/dleV2.js @@ -18,6 +18,7 @@ const auth = require('../middleware/auth'); const path = require('path'); const fs = require('fs'); const ethers = require('ethers'); // Added ethers for private key validation +const create2 = require('../utils/create2'); /** * @route POST /api/dle-v2 @@ -298,4 +299,34 @@ router.post('/validate-private-key', async (req, res, next) => { } }); -module.exports = router; \ No newline at end of file +module.exports = router; + +/** + * Дополнительные маршруты (подключаются из app.js) + */ + +// Предсказание адресов по выбранным сетям с использованием CREATE2 +router.post('/predict-addresses', auth.requireAuth, auth.requireAdmin, async (req, res) => { + try { + const { name, symbol, selectedNetworks } = req.body || {}; + if (!selectedNetworks || !Array.isArray(selectedNetworks) || selectedNetworks.length === 0) { + return res.status(400).json({ success: false, message: 'Не переданы сети' }); + } + + // Используем служебные секреты для фабрики и SALT + // Ожидаем, что на сервере настроены переменные окружения или конфиги на сеть + const result = {}; + for (const chainId of selectedNetworks) { + const factory = process.env[`FACTORY_ADDRESS_${chainId}`] || process.env.FACTORY_ADDRESS; + const saltHex = process.env[`CREATE2_SALT_${chainId}`] || process.env.CREATE2_SALT; + const initCodeHash = process.env[`INIT_CODE_HASH_${chainId}`] || process.env.INIT_CODE_HASH; + if (!factory || !saltHex || !initCodeHash) continue; + result[chainId] = create2.computeCreate2Address(factory, saltHex, initCodeHash); + } + + return res.json({ success: true, data: result }); + } catch (e) { + logger.error('predict-addresses error', e); + return res.status(500).json({ success: false, message: 'Ошибка расчета адресов' }); + } +}); \ No newline at end of file diff --git a/backend/scripts/deploy/create-dle-v2.js b/backend/scripts/deploy/create-dle-v2.js index d0ce62d..33c7cb5 100644 --- a/backend/scripts/deploy/create-dle-v2.js +++ b/backend/scripts/deploy/create-dle-v2.js @@ -1,3 +1,71 @@ +/* eslint-disable no-console */ +const hre = require('hardhat'); + +async function main() { + const { ethers } = hre; + const rpcUrl = process.env.RPC_URL; + const pk = process.env.PRIVATE_KEY; + if (!rpcUrl || !pk) throw new Error('RPC_URL/PRIVATE_KEY required'); + + const provider = new ethers.JsonRpcProvider(rpcUrl); + const wallet = new ethers.Wallet(pk, provider); + + const salt = process.env.CREATE2_SALT; + const initCodeHash = process.env.INIT_CODE_HASH; + let factoryAddress = process.env.FACTORY_ADDRESS; + + if (!salt || !initCodeHash) throw new Error('CREATE2_SALT/INIT_CODE_HASH required'); + + // Ensure factory + if (!factoryAddress) { + const Factory = await hre.ethers.getContractFactory('FactoryDeployer', wallet); + const factory = await Factory.deploy(); + await factory.waitForDeployment(); + factoryAddress = await factory.getAddress(); + } else { + const code = await provider.getCode(factoryAddress); + if (code === '0x') { + const Factory = await hre.ethers.getContractFactory('FactoryDeployer', wallet); + const factory = await Factory.deploy(); + await factory.waitForDeployment(); + factoryAddress = await factory.getAddress(); + } + } + + // Prepare DLE init code = creation bytecode WITH constructor args + const DLE = await hre.ethers.getContractFactory('DLE', wallet); + const paramsPath = require('path').join(__dirname, './current-params.json'); + const params = require(paramsPath); + const dleConfig = { + name: params.name, + symbol: params.symbol, + location: params.location, + coordinates: params.coordinates, + jurisdiction: params.jurisdiction, + oktmo: params.oktmo, + okvedCodes: params.okvedCodes || [], + kpp: params.kpp, + quorumPercentage: params.quorumPercentage, + initialPartners: params.initialPartners, + initialAmounts: params.initialAmounts, + supportedChainIds: params.supportedChainIds + }; + const deployTx = await DLE.getDeployTransaction(dleConfig, params.currentChainId); + const dleInit = deployTx.data; // полноценный init code + + // Deploy via factory + const Factory = await hre.ethers.getContractAt('FactoryDeployer', factoryAddress, wallet); + const tx = await Factory.deploy(salt, dleInit); + const rc = await tx.wait(); + const addr = rc.logs?.[0]?.args?.addr || (await Factory.computeAddress(salt, initCodeHash)); + console.log('DLE v2 задеплоен по адресу:', addr); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); + /** * Copyright (c) 2024-2025 Тарабанов Александр Викторович * All rights reserved. diff --git a/backend/scripts/deploy/deploy-multichain.js b/backend/scripts/deploy/deploy-multichain.js new file mode 100644 index 0000000..12fef56 --- /dev/null +++ b/backend/scripts/deploy/deploy-multichain.js @@ -0,0 +1,69 @@ +/* eslint-disable no-console */ +const hre = require('hardhat'); +const path = require('path'); + +async function deployInNetwork(rpcUrl, pk, salt, initCodeHash, factoryAddress, dleInit) { + const { ethers } = hre; + const provider = new ethers.JsonRpcProvider(rpcUrl); + const wallet = new ethers.Wallet(pk, provider); + + // Ensure factory + let faddr = factoryAddress; + const code = faddr ? await provider.getCode(faddr) : '0x'; + if (!faddr || code === '0x') { + const Factory = await hre.ethers.getContractFactory('FactoryDeployer', wallet); + const factory = await Factory.deploy(); + await factory.waitForDeployment(); + faddr = await factory.getAddress(); + } + const Factory = await hre.ethers.getContractAt('FactoryDeployer', faddr, wallet); + const tx = await Factory.deploy(salt, dleInit); + const rc = await tx.wait(); + const addr = rc.logs?.[0]?.args?.addr || (await Factory.computeAddress(salt, initCodeHash)); + return { factory: faddr, address: addr }; +} + +async function main() { + const { ethers } = hre; + const pk = process.env.PRIVATE_KEY; + const salt = process.env.CREATE2_SALT; + const initCodeHash = process.env.INIT_CODE_HASH; + const networks = (process.env.MULTICHAIN_RPC_URLS || '').split(',').map(s => s.trim()).filter(Boolean); + const factories = (process.env.MULTICHAIN_FACTORY_ADDRESSES || '').split(',').map(s => s.trim()); + + if (!pk || !salt || !initCodeHash || networks.length === 0) throw new Error('Env: PRIVATE_KEY, CREATE2_SALT, INIT_CODE_HASH, MULTICHAIN_RPC_URLS'); + + // Prepare init code once + const paramsPath = path.join(__dirname, './current-params.json'); + const params = require(paramsPath); + const DLE = await hre.ethers.getContractFactory('DLE'); + const dleConfig = { + name: params.name, + symbol: params.symbol, + location: params.location, + coordinates: params.coordinates, + jurisdiction: params.jurisdiction, + oktmo: params.oktmo, + okvedCodes: params.okvedCodes || [], + kpp: params.kpp, + quorumPercentage: params.quorumPercentage, + initialPartners: params.initialPartners, + initialAmounts: params.initialAmounts, + supportedChainIds: params.supportedChainIds + }; + const deployTx = await DLE.getDeployTransaction(dleConfig, params.currentChainId); + const dleInit = deployTx.data; + + const results = []; + for (let i = 0; i < networks.length; i++) { + const rpcUrl = networks[i]; + const factory = factories[i] || process.env.FACTORY_ADDRESS || null; + const r = await deployInNetwork(rpcUrl, pk, salt, initCodeHash, factory, dleInit); + results.push({ rpcUrl, ...r }); + } + console.log('MULTICHAIN_DEPLOY_RESULT', JSON.stringify(results)); +} + +main().catch((e) => { console.error(e); process.exit(1); }); + + diff --git a/backend/services/dleV2Service.js b/backend/services/dleV2Service.js index e9f0ceb..9bc22e6 100644 --- a/backend/services/dleV2Service.js +++ b/backend/services/dleV2Service.js @@ -49,59 +49,48 @@ class DLEV2Service { fs.copyFileSync(paramsFile, tempParamsFile); logger.info(`Файл параметров скопирован успешно`); - // Определяем сеть для деплоя (берем первую из выбранных сетей) - const chainId = deployParams.supportedChainIds && deployParams.supportedChainIds.length > 0 - ? deployParams.supportedChainIds[0] - : 1; // По умолчанию Ethereum - - // Получаем rpc_url из базы по chain_id - logger.info(`Поиск RPC URL для chain_id: ${chainId}`); - const rpcUrl = await getRpcUrlByChainId(chainId); - if (!rpcUrl) { - logger.error(`RPC URL для сети с chain_id ${chainId} не найден в базе данных`); - throw new Error(`RPC URL для сети с chain_id ${chainId} не найден в базе данных`); + // Готовим RPC для всех выбранных сетей + const rpcUrls = []; + for (const cid of deployParams.supportedChainIds) { + logger.info(`Поиск RPC URL для chain_id: ${cid}`); + const ru = await getRpcUrlByChainId(cid); + if (!ru) { + throw new Error(`RPC URL для сети с chain_id ${cid} не найден в базе данных`); + } + rpcUrls.push(ru); } - logger.info(`Найден RPC URL для chain_id ${chainId}: ${rpcUrl}`); - - // Проверяем баланс кошелька - const { ethers } = require('ethers'); - const provider = new ethers.JsonRpcProvider(rpcUrl); - const walletAddress = dleParams.privateKey ? new ethers.Wallet(dleParams.privateKey, provider).address : null; - - if (walletAddress) { - const balance = await provider.getBalance(walletAddress); - const minBalance = ethers.parseEther("0.00001"); // Временно уменьшено для тестирования - logger.info(`Баланс кошелька ${walletAddress}: ${ethers.formatEther(balance)} ETH`); - - if (balance < minBalance) { - logger.warn(`Недостаточно ETH для деплоя. Баланс: ${ethers.formatEther(balance)} ETH, требуется минимум: ${ethers.formatEther(minBalance)} ETH`); - throw new Error(`Недостаточно ETH для деплоя. Баланс: ${ethers.formatEther(balance)} ETH, требуется минимум: ${ethers.formatEther(minBalance)} ETH. Пополните кошелек через Sepolia faucet: https://sepoliafaucet.com/`); + + // Лёгкая проверка баланса в первой сети + { + const { ethers } = require('ethers'); + const provider = new ethers.JsonRpcProvider(rpcUrls[0]); + const walletAddress = dleParams.privateKey ? new ethers.Wallet(dleParams.privateKey, provider).address : null; + if (walletAddress) { + const balance = await provider.getBalance(walletAddress); + const minBalance = ethers.parseEther("0.00001"); + logger.info(`Баланс кошелька ${walletAddress}: ${ethers.formatEther(balance)} ETH`); + if (balance < minBalance) { + throw new Error(`Недостаточно ETH для деплоя в ${deployParams.supportedChainIds[0]}. Баланс: ${ethers.formatEther(balance)} ETH`); + } } } if (!dleParams.privateKey) { throw new Error('Приватный ключ для деплоя не передан'); } - // Маппинг chain_id к именам сетей в Hardhat - const chainIdToNetworkName = { - 1: 'ethereum', - 137: 'polygon', - 56: 'bsc', - 42161: 'arbitrum', - 11155111: 'sepolia' - }; - - const networkName = chainIdToNetworkName[chainId]; - if (!networkName) { - throw new Error(`Сеть с chain_id ${chainId} не поддерживается для деплоя`); - } + // Рассчитываем INIT_CODE_HASH автоматически из актуального initCode + const initCodeHash = await this.computeInitCodeHash(deployParams); - // Запускаем скрипт деплоя с нужными переменными окружения - const result = await this.runDeployScript(paramsFile, { - rpcUrl, + // Собираем адреса фабрик по сетям (если есть) + const factoryAddresses = deployParams.supportedChainIds.map(cid => process.env[`FACTORY_ADDRESS_${cid}`] || '').join(','); + + // Мультисетевой деплой одним вызовом + const result = await this.runDeployMultichain(paramsFile, { + rpcUrls: rpcUrls.join(','), privateKey: dleParams.privateKey, - networkId: networkName, - envNetworkKey: chainId.toString().toUpperCase() + salt: process.env.CREATE2_SALT, + initCodeHash, + factories: factoryAddresses }); // Очищаем временные файлы @@ -237,14 +226,12 @@ class DLEV2Service { return; } - // Формируем переменные окружения для скрипта деплоя const envVars = { ...process.env, RPC_URL: extraEnv.rpcUrl, PRIVATE_KEY: extraEnv.privateKey }; - // Запускаем скрипт без указания сети, передаем RPC URL и приватный ключ через переменные окружения const hardhatProcess = spawn('npx', ['hardhat', 'run', scriptPath], { cwd: path.join(__dirname, '..'), env: envVars, @@ -266,7 +253,6 @@ class DLEV2Service { hardhatProcess.on('close', (code) => { try { - // Пытаемся извлечь результат из stdout независимо от кода завершения const result = this.extractDeployResult(stdout); resolve(result); } catch (error) { @@ -286,6 +272,40 @@ class DLEV2Service { }); } + // Мультисетевой деплой + runDeployMultichain(paramsFile, opts = {}) { + return new Promise((resolve, reject) => { + const scriptPath = path.join(__dirname, '../scripts/deploy/deploy-multichain.js'); + if (!fs.existsSync(scriptPath)) return reject(new Error('Скрипт мультисетевого деплоя не найден')); + const envVars = { + ...process.env, + PRIVATE_KEY: opts.privateKey, + CREATE2_SALT: opts.salt, + INIT_CODE_HASH: opts.initCodeHash, + MULTICHAIN_RPC_URLS: opts.rpcUrls, + MULTICHAIN_FACTORY_ADDRESSES: opts.factories || '' + }; + const p = spawn('npx', ['hardhat', 'run', scriptPath], { cwd: path.join(__dirname, '..'), env: envVars, stdio: 'pipe' }); + let stdout = '', stderr = ''; + p.stdout.on('data', (d) => { stdout += d.toString(); logger.info(`[MULTI] ${d.toString().trim()}`); }); + p.stderr.on('data', (d) => { stderr += d.toString(); logger.error(`[MULTI_ERR] ${d.toString().trim()}`); }); + p.on('close', () => { + try { + const m = stdout.match(/MULTICHAIN_DEPLOY_RESULT\s*(\[.*\])/s); + if (!m) throw new Error('Результат не найден'); + const arr = JSON.parse(m[1]); + const addr = arr[0].address; + const allSame = arr.every(x => x.address.toLowerCase() === addr.toLowerCase()); + if (!allSame) throw new Error('Адреса отличаются между сетями'); + resolve({ success: true, data: { dleAddress: addr, networks: arr } }); + } catch (e) { + reject(new Error(`Ошибка мультисетевого деплоя: ${e.message}\nSTDOUT:${stdout}\nSTDERR:${stderr}`)); + } + }); + p.on('error', (e) => reject(e)); + }); + } + /** * Извлекает результат деплоя из stdout * @param {string} stdout - Вывод скрипта @@ -358,6 +378,30 @@ class DLEV2Service { return []; } } + + // Авто-расчёт INIT_CODE_HASH + async computeInitCodeHash(params) { + const hre = require('hardhat'); + const { ethers } = hre; + const DLE = await hre.ethers.getContractFactory('DLE'); + const dleConfig = { + name: params.name, + symbol: params.symbol, + location: params.location, + coordinates: params.coordinates, + jurisdiction: params.jurisdiction, + oktmo: params.oktmo, + okvedCodes: params.okvedCodes || [], + kpp: params.kpp, + quorumPercentage: params.quorumPercentage, + initialPartners: params.initialPartners, + initialAmounts: params.initialAmounts, + supportedChainIds: params.supportedChainIds + }; + const deployTx = await DLE.getDeployTransaction(dleConfig, params.currentChainId); + const initCode = deployTx.data; + return ethers.keccak256(initCode); + } } module.exports = new DLEV2Service(); \ No newline at end of file diff --git a/backend/services/telegramBot.js b/backend/services/telegramBot.js index 215c0d0..3cbdb61 100644 --- a/backend/services/telegramBot.js +++ b/backend/services/telegramBot.js @@ -416,8 +416,9 @@ async function getBot() { if (recentMessages && recentMessages.length > 0) { // Преобразуем сообщения в формат для AI history = recentMessages.reverse().map(msg => ({ - role: msg.sender_type === 'user' ? 'user' : 'assistant', - content: msg.content || '' // content уже расшифрован encryptedDb + // Любые человеческие роли трактуем как 'user', только ответы ассистента — 'assistant' + role: msg.sender_type === 'assistant' ? 'assistant' : 'user', + content: msg.content || '' })); } } catch (historyError) { @@ -465,7 +466,7 @@ async function getBot() { sender_type: 'assistant', content: aiResponse, channel: 'telegram', - role: role, + role: 'assistant', direction: 'out', created_at: new Date() }); diff --git a/backend/utils/create2.js b/backend/utils/create2.js new file mode 100644 index 0000000..0509f15 --- /dev/null +++ b/backend/utils/create2.js @@ -0,0 +1,21 @@ +const { keccak256, getAddress } = require('ethers').utils || require('ethers'); + +function toBytes(hex) { + if (hex.startsWith('0x')) return Buffer.from(hex.slice(2), 'hex'); + return Buffer.from(hex, 'hex'); +} + +function computeCreate2Address(factory, saltHex, initCodeHash) { + const parts = [ + '0xff', + factory.toLowerCase(), + saltHex.toLowerCase(), + initCodeHash.toLowerCase() + ].map(x => x.startsWith('0x') ? x.slice(2) : x).join(''); + const hash = '0x' + require('crypto').createHash('sha3-256').update(Buffer.from(parts, 'hex')).digest('hex'); + return '0x' + hash.slice(-40); +} + +module.exports = { computeCreate2Address }; + + diff --git a/docs/DLE_CONSOLIDATED_ANALYSIS.md b/docs/DLE_CONSOLIDATED_ANALYSIS.md index aac4cca..38e48d3 100644 --- a/docs/DLE_CONSOLIDATED_ANALYSIS.md +++ b/docs/DLE_CONSOLIDATED_ANALYSIS.md @@ -10,6 +10,18 @@ GitHub: https://github.com/HB3-ACCELERATOR --> +# DLE v2 — краткие обновления + +- Single‑Chain Governance: голосование фиксируется в одной сети, исполнение в целевых сетях по EIP‑712 подписям без внешних мостов. +- Снапшоты голосующей силы: `ERC20Votes` (`getPastVotes`, `getPastTotalSupply`) исключают перелив голосов. +- Делегирование «только на себя»: 1 токен = 1 голос, запрет делегирования третьим лицам. +- Модульность: казна, таймлок, деактивация, коммуникации выделены в отдельные модули, операции выполняются через ядро DLE. +- «100% или ничего»: много-сетевые операции исполняются только при готовности всех целевых сетей. +- Детерминированный деплой: `FactoryDeployer` + CREATE2 для одинаковых адресов во всех выбранных сетях; INIT_CODE_HASH рассчитывается автоматически из актуального initCode. +- Аналитика: добавлены view‑функции для сводок, пагинации и агрегирования по предложениям. + +--- + # DLE - Единый Смарт-Контракт с Модульной Архитектурой ## 🎯 ПОЛНОЕ ПОНИМАНИЕ ЗАДАЧИ DLE @@ -51,12 +63,12 @@ DLE (Digital Legal Entity) = Универсальная цифровая юри ### **3. СИСТЕМА УПРАВЛЕНИЯ:** -#### **Голосование и мультиподпись:** +#### **Голосование токен‑холдеров:** ``` - Только токен-холдеры участвуют в управлении - Каждый токен = одна голосующая сила - Кворум настраиваемый (например, 60% от общего количества токенов) -- Мультиподпись через токен-холдеров (проверка баланса при каждой операции) +- Коллективное голосование токен‑холдеров (ERC20Votes снапшоты) ``` #### **Создание предложений:** @@ -101,7 +113,6 @@ DLE (Digital Legal Entity) = Универсальная цифровая юри ``` - ERC-20 токены - Система голосования -- Мультиподпись - Мультичейн синхронизация - Управление модулями - DLEInfo (юридическая информация) @@ -141,7 +152,7 @@ DLE (Digital Legal Entity) = Универсальная цифровая юри ``` - Только токен-холдеры управляют - Проверка баланса при каждой операции -- Кворум мультиподписей +- Кворум голосов - все решения через коллективное голосование - Синхронизация между цепочками ``` @@ -174,7 +185,7 @@ DLE.sol (Основной контракт) + Модули (добавляемы 1. **Один основной контракт** - управление токенами, голосованием, мультиподписью 2. **Модули** - специализированные функции (казначейство, иерархическое голосование, коммуникации) 3. **Только токен-холдеры** - никаких админских ролей -4. **Кворум мультиподписей** - все решения через коллективное голосование +4. **Кворум голосов** - все решения через коллективное голосование 5. **Проверка баланса** - при каждой операции --- @@ -190,7 +201,7 @@ DLE.sol ├── Выбор цепочки для кворума (governanceChainId) ├── Синхронизация голосов между цепочками ├── Поддержка множественных цепочек -├── Мультиподпись (через токен-холдеров) +├── Голосование токен‑холдеров ├── Мультичейн синхронизация └── Система модулей (добавление/управление) ``` @@ -216,7 +227,7 @@ DLE.sol - **Выбор цепочки для кворума** - токен-холдер может выбрать любую поддерживаемую цепочку - **Синхронизация голосов** - после голосования результаты синхронизируются между цепочками - **Поддержка множественных цепочек** - Ethereum, Polygon, BSC и др. -- **Мультиподпись** - через токен-холдеров с проверкой баланса +- **Голосование** - через токен‑холдеров с проверкой баланса - **Мультичейн синхронизация** - одинаковый адрес во всех цепочках - **Управление модулями** - добавление/удаление через голосование @@ -241,14 +252,14 @@ DLE.sol ### 5. ExternalDLEModule.sol ✅ - **Меж-DLE взаимодействие** - управление DLE B через приложение DLE A - **Встраивание интерфейсов** - безопасное управление -- **Проверка прав** - через мультиподпись +- **Проверка прав** - через голосование токен‑холдеров - **Аудит действий** - отслеживание операций ### 6. Мульти-чейн архитектура ✅ - **CREATE2 деплой** - одинаковый адрес во всех цепочках - **Синхронизация состояния** - токены, предложения, голосования - **Создание предложений** - в любой цепочке -- **Голосование** - в любой цепочке с синхронизацией +- **Голосование** - через токен‑холдеров с проверкой баланса --- @@ -257,7 +268,7 @@ DLE.sol ### Основные принципы безопасности: 1. **Только токен-холдеры** - никаких админских ролей 2. **Проверка баланса** - при каждой операции -3. **Кворум мультиподписей** - все решения коллективные +3. **Кворум голосов** - все решения коллективные 4. **Простая логика** - минимум уязвимостей ### Защита от атак: @@ -503,13 +514,10 @@ function createProposal( uint256 _governanceChainId ) external returns (uint256); -// Синхронизация голосов между цепочками -function syncVoteFromChain( - uint256 _proposalId, - uint256 _fromChainId, - uint256 _forVotes, - uint256 _againstVotes, - bytes memory _proof +// Исполнение в целевых сетях по EIP-712 подписям (без мостов) +function executeProposalBySignatures( + uint256 proposalId, + bytes[] calldata signatures ) external; // Проверка поддерживаемых цепочек @@ -517,29 +525,8 @@ function isChainSupported(uint256 _chainId) external view returns (bool); ``` ### Синхронизация между цепочками -```solidity -// Синхронизация токенов -function syncTokenBalance( - address holder, - uint256 balance, - uint256 fromChainId -) external; - -// Синхронизация предложений -function syncProposal( - uint256 proposalId, - Proposal memory proposal, - uint256 fromChainId -) external; - -// Синхронизация голосов -function syncVote( - uint256 proposalId, - address voter, - bool support, - uint256 fromChainId -) external; -``` +- Результаты голосования фиксируются снапшотами ERC20Votes в governance‑сети. +- Целевые сети принимают исполнение при верификации EIP‑712 подписей холдеров и кворума на зафиксированном timepoint. --- @@ -940,7 +927,7 @@ contract DLE is ERC20, ReentrancyGuard { ### ✅ Безопасность - Никаких админских ролей -- Простая логика мультиподписи +- Простая логика коллективного голосования - Защита от основных атак - Прозрачность всех операций @@ -962,7 +949,7 @@ contract DLE is ERC20, ReentrancyGuard { **DLE - это единый смарт-контракт с модульной архитектурой, который:** -1. **Управляется только токен-холдерами** через кворум мультиподписей +1. **Управляется только токен‑холдерами** через кворум голосов 2. **Проверяет баланс токенов** при каждой операции 3. **Использует модули** для специализированных функций 4. **Синхронизируется между цепочками** с одинаковым адресом diff --git a/docs/DLE_MANAGEMENT_TASKS.md b/docs/DLE_MANAGEMENT_TASKS.md index 67d373e..ed7d114 100644 --- a/docs/DLE_MANAGEMENT_TASKS.md +++ b/docs/DLE_MANAGEMENT_TASKS.md @@ -16,7 +16,7 @@ ### Архитектурные требования - **Single-Chain Governance**: Голосование происходит только в одной выбранной сети -- **Мультиподпись токен-холдеров**: Все операции требуют кворума подписей +- **Кворум голосов токен‑холдеров**: Все операции требуют достижения кворума голосующей силы по снапшотам - **Настраиваемые таймлоки**: Инициатор устанавливает задержку для каждого предложения - **Cross-chain исполнение**: Решения выполняются во всех целевых сетях - **Без админских ролей**: Только коллективное управление через токен-холдеров @@ -24,11 +24,23 @@ ### Технический стек - **Frontend**: Vue.js 3 + Composition API - **Web3**: ethers.js или web3.js -- **Контракты**: Solidity + OpenZeppelin + ERC-4337 +- **Контракты**: Solidity + OpenZeppelin (ERC‑4337 опционально для кошельков/UX) - **Стили**: Scoped CSS с переменными --- +## Обновления (DLE v2) + +- Деплой: + - Мультисетевой деплой одной кнопкой: backend вызывает `deploy-multichain.js`. + - Предсказанные адреса DLE отображаются автоматически (endpoint `/api/dle-v2/predict-addresses`). + - INIT_CODE_HASH вычисляется автоматически на backend, не вводится вручную. +- Предложения (UI): + - Порядок секций: Базовая информация → Timelock → Governance‑сеть → Целевые сети → Тип операции и параметры → Предпросмотр. + - Поля: `timelockHours`, `targetChains`, `governanceChainId`. +- Аналитика: + - Использовать новые view‑функции: `getProposalSummary`, `getProposalState`, `getProposalVotes`, `getQuorumAt`, `getVotingPowerAt`, `listSupportedChains`, `getGovernanceParams`. + ## 1. БЛОК "ПРЕДЛОЖЕНИЯ" (`/management/proposals`) ### Задача 1.1: Создание предложений diff --git a/docs/MODULE_ARCHITECTURE.md b/docs/MODULE_ARCHITECTURE.md index 634e0a3..494b2a9 100644 --- a/docs/MODULE_ARCHITECTURE.md +++ b/docs/MODULE_ARCHITECTURE.md @@ -105,4 +105,19 @@ contract GovernanceModule { - Проверяйте права доступа - Тестируйте граничные случаи - Валидируйте входные параметры -- Проверяйте обработку ошибок \ No newline at end of file +- Проверяйте обработку ошибок + +# Модульная архитектура (обновление для DLE v2) + +- Модули выносятся в отдельные контракты: `TreasuryModule`, `TimelockModule`, `DeactivationModule`, `CommunicationModule`. +- Подключение/отключение модулей — строго через предложения DLE (`ModuleAdded`/`ModuleRemoved`). +- Исполнение модульных операций инициируется основным DLE через `_executeOperation` по безопасному `operationCalldata`. +- Денежные переводы из ядра исключены: все токено‑операции внутри `TreasuryModule`. +- Таймлок применяется на уровне предложения: `timelockHours` хранится в `Proposal` и проверяется при исполнении. +- Для оффчейн действий ядро эмитит событие `OffchainAction`, которое подписывает и обрабатывает бекенд/клиент. + +Последовательность для казначейской операции: +1) Создание предложения с типом операции и параметрами, указание `governanceChainId`, `targetChains`, `timelockHours`. +2) Сбор голосов в выбранной сети (снапшоты ERC20Votes). +3) По наступлению timelock — `executeProposalBySignatures` в целевых сетях с проверкой EIP‑712 подписей и «100% или ничего». +4) Ядро вызывает `TreasuryModule` по `abi.encodeWithSelector(...)`. \ No newline at end of file diff --git a/docs/SMART_CONTRACTS.md b/docs/SMART_CONTRACTS.md index 4918ed5..7eb07e3 100644 --- a/docs/SMART_CONTRACTS.md +++ b/docs/SMART_CONTRACTS.md @@ -14,8 +14,64 @@ ## Основной смарт контракт DLE +### DLE v2: ключевые изменения и API (актуально) +- Безопасность: удалены уязвимые Merkle‑механизмы cross‑chain; нет внешних мостов/оракулов. +- Голосующая сила: OpenZeppelin `ERC20Votes` (снимки `getPastVotes`, `getPastTotalSupply`). +- Делегирование: жестко ограничено «только на себя»; третьим лицам делегировать нельзя (1 токен = 1 голос). +- Single‑Chain Governance: голосование происходит в одной выбранной сети (`governanceChainId`), время снапшота фиксируется на создании предложения и используется во всех сетях. +- Multi‑Chain исполнение: выполнение в целевых сетях по EIP‑712 подписям холдеров, проверяется суммарная голосующая сила на зафиксированном `timepoint` (без доверия к мостам). +- «100% или ничего»: операции считаются успешными только при готовности/успешности всех целевых сетей. +- Модули вынесены отдельно: `Treasury`, `Timelock`, `Deactivation`, `Communication` и др. Управление только через предложения. +- Детерминированные адреса: фабрика `FactoryDeployer` + CREATE2. Единый адрес DLE и модулей во всех выбранных сетях. INIT_CODE_HASH автоподставляется из актуального initCode. +- Аналитика: добавлены view‑функции для агрегирования и пагинации. + +Пример основных функций DLE v2 (интерфейс): +```solidity +// Создание предложения с фиксацией сети голосования, целевых сетей и таймлока +function createProposal( + string calldata description, + uint256 governanceChainId, + uint256[] calldata targetChains, + uint64 timelockHours, + bytes calldata operationCalldata +) external returns (uint256 proposalId); + +// Голосование с использованием снапшотов ERC20Votes (учет силы на момент создания) +function vote(uint256 proposalId, bool support) external; + +// Отмена инициатором при наличии достаточной голосующей силы (мягкая отмена) +function cancelProposal(uint256 proposalId) external; + +// Исполнение в целевой сети по EIP-712 подписям холдеров (без мостов) +function executeProposalBySignatures( + uint256 proposalId, + bytes[] calldata signatures +) external; + +// Просмотровые функции (аналитика) +function getProposalState(uint256 proposalId) external view returns (uint8); +function getProposalVotes(uint256 proposalId) external view returns (uint256 forVotes, uint256 againstVotes); +function getQuorumAt(uint256 timepoint) external view returns (uint256); +function getVotingPowerAt(address account, uint256 timepoint) external view returns (uint256); +function getProposalSummary(uint256 proposalId) external view returns (/* агрегированные поля */); +function getGovernanceParams() external view returns (/* кворум, снапшоты, chainIds */); +function listSupportedChains() external view returns (uint256[] memory); +``` + +События (ключевые): +- `ProposalCreated`, `ProposalCancelled`, `ProposalExecuted` +- `OffchainAction` (триггер оффчейн‑действий через события) +- `ModuleAdded`, `ModuleRemoved` + +Замечания по безопасности: +- Снапшоты голосующей силы через `ERC20Votes` исключают перелив голосов. +- Верификация EIP‑712 подписей исключает зависимость от внешних мостов. +- Отсутствуют админ‑роли: все изменения только предложением и кворумом. +- Защита от повторов: `nonces` и EIP‑712 схемы подписи используются по стандарту OZ. +``` + ### Концепция -**Один смарт-контракт** с ERC-20 токенами, настраиваемым кворумом, мультиподписью и модулями. Адрес контракта одновременно выполняет функции банковского счета и контактных данных. +**Один смарт-контракт** с ERC-20 токенами, настраиваемым кворумом и модулями. Адрес контракта одновременно выполняет функции банковского счета и контактных данных. ### Архитектура ``` @@ -23,7 +79,7 @@ DLE.sol (Один контракт) ├── ERC-20 токены (голосующая сила) ├── Настраиваемый кворум (% от общего количества токенов) ├── Система голосования (проверка баланса токенов) -├── Мультиподпись (через токен-холдеров) +├── Голосование токен‑холдеров ├── Модули (добавляемые через голосование) ├── Мультичейн синхронизация └── Полное управление данными DLE через кворум @@ -70,13 +126,12 @@ DLE.sol (Один контракт) - **Изменение процента кворума** через кворум - **Изменение текущей цепочки** через кворум -#### 5. Мультиподпись через токен-холдеров -- **Описание**: Система подписей для критических операций +#### 5. Голосование токен‑холдеров +- **Описание**: Критические операции подтверждаются голосованием держателей токенов - **Функции**: - - Подписание операций токен-холдерами - - Проверка баланса токенов при подписи - - Сбор подписей до достижения кворума - - Выполнение операций после сбора подписей + - Подача голосов за/против с учетом голосующей силы + - Подсчет голосов по снапшотам `ERC20Votes` + - Исполнение операций после достижения кворума #### 6. Казначейские функции - **Описание**: Управление финансами DLE через голосование @@ -110,7 +165,7 @@ DLE может владеть токенами других DLE и участв #### Механизм работы 1. **DLE A** владеет токенами **DLE B** 2. **Голос DLE A** в **DLE B** прямо пропорционален количеству токенов **DLE B** на балансе **DLE A** -3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум мультиподписей** внутри **DLE A** +3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум голосов** внутри **DLE A** 4. После достижения кворума подписей **DLE A** может голосовать в **DLE B** как единое целое ### Новые возможности изменения данных DLE ✅ @@ -165,7 +220,7 @@ event CurrentChainIdUpdated(uint256 oldChainId, uint256 newChainId); #### 4. Синхронизация - Изменения синхронизируются во все поддерживаемые цепочки -- Merkle proofs обеспечивают безопасность cross-chain операций +- EIP‑712 подписи холдеров обеспечивают безопасность cross-chain исполнения (без мостов) ### Примеры использования @@ -203,7 +258,7 @@ event CurrentChainIdUpdated(uint256 oldChainId, uint256 newChainId); #### Защита от злоупотреблений - Все изменения только через кворум - Проверка баланса токенов при голосовании -- Merkle proofs для cross-chain безопасности +- EIP‑712 подписи и проверка снапшотов для cross-chain безопасности #### Аудит изменений - Все изменения логируются в событиях @@ -218,7 +273,7 @@ DLE может владеть токенами других DLE и участв #### Механизм работы 1. **DLE A** владеет токенами **DLE B** 2. **Голос DLE A** в **DLE B** прямо пропорционален количеству токенов **DLE B** на балансе **DLE A** -3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум мультиподписей** внутри **DLE A** +3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум голосов** внутри **DLE A** 4. После достижения кворума подписей **DLE A** может голосовать в **DLE B** как единое целое #### Пример @@ -228,8 +283,8 @@ DLE может владеть токенами других DLE и участв - **DLE B** получает от **DLE A** подпись на **10% голосов** #### Технические требования -- Система сбора мультиподписей внутри DLE для внешнего голосования -- Проверка кворума подписей перед активацией голоса DLE +- Система сбора голосов внутри DLE для внешнего голосования +- Проверка прав через голосование - Прямо пропорциональный подсчет голосов по количеству токенов - Интерфейсы для взаимодействия между DLE @@ -272,11 +327,11 @@ function DLEBManagementInterface({ dleBAddress }) { - URL: `http://localhost:5173/dle-management` - Встраивание компонентов управления DLE B - Безопасное подписание транзакций для DLE B -- Проверка прав через мультиподпись +- Проверка прав через голосование ### Технические требования - Один адрес = универсальная точка входа -- Безопасность мультиподписи через токен-холдеров +- Безопасность коллективного голосования токен‑холдеров по снапшотам - Масштабируемость через модули - Поддержка аудио/видео коммуникации - Совместимость с существующими стандартами (ERC-20, ERC-721) @@ -299,12 +354,12 @@ DLE должен функционировать в нескольких блок #### 2. Синхронные токены управления - Одинаковое количество токенов для каждого партнера во всех сетях - Синхронизация операций с токенами между всеми развернутыми сетями -- Все операции с токенами только через мультиподпись и кворум +- Все операции с токенами только через кворум голосов - Защита от double-spending и рассинхронизации #### 3. Single-Chain Governance система - Инициатор предложения выбирает ОДНУ сеть для голосования -- Все токен-холдеры участвуют в мультиподписи только в выбранной сети +- Все токен-холдеры участвуют в голосовании только в выбранной сети - Инициатор устанавливает таймлок для предложения - Проверка балансов токен-холдеров при подписании - Исполнение решения происходит во всех целевых сетях @@ -408,7 +463,7 @@ contract DLE_SingleChainGovernance { ERC-4337 предоставляет стандартную инфраструктуру для смарт-контракт кошельков с универсальностью (один адрес во всех цепочках) и готовыми решениями для оптимизации газа. #### Компоненты ERC-4337 -- **Smart Contract Wallets** - встроенная мультиподпись +- **Smart Contract Wallets** — инфраструктура аккаунтов (опционально для UX) - **Bundlers** - оптимизация газа через агрегацию транзакций - **Paymasters** - гибкая оплата транзакций - **Account Abstraction** - универсальность и стандартизация @@ -449,7 +504,7 @@ ERC-4337 распространяется под лицензией **CC0** (Pub - ✅ **ERC-20** - токены управления - ✅ **Governance** - система голосования - ✅ **Access Control** - роли и разрешения -- ✅ **Multisig** - мультиподпись +(устарело) Multisig — используем голосование токен‑холдеров (ERC20Votes) - ✅ **Timelock** - задержки выполнения ### 2. **ERC-4337** (аудит: Trail of Bits) @@ -475,7 +530,7 @@ contract DLE is ERC20, Governor, TimelockController { ### **Компоненты для интеграции:** - **ERC-20** - токен управления DLE -- **Governor** - система голосования с мультиподписью +- **Governor** - система голосования - **TimelockController** - настраиваемые таймлоки - **Account Abstraction** - универсальность адреса @@ -493,10 +548,13 @@ contract DLE is ERC20, Governor, TimelockController { ### ✅ **Надежность** - Временем проверенные решения -- Простая логика мультиподписи токен-холдеров +- Простая логика коллективного голосования токен‑холдеров - Понятные механизмы таймлоков ### ✅ **Совместимость** - Стандартные интерфейсы Ethereum - Совместимость с существующими кошельками -- Легкая интеграция с DeFi протоколами \ No newline at end of file +- Легкая интеграция с DeFi протоколами + +### Примечание про ERC-4337 (опционально) +- Может использоваться в кошельках/окружении для UX (userOps), но не является частью ядра DLE v2. \ No newline at end of file diff --git a/frontend/src/utils/dle-contract.js b/frontend/src/utils/dle-contract.js index 593550a..a2509a3 100644 --- a/frontend/src/utils/dle-contract.js +++ b/frontend/src/utils/dle-contract.js @@ -84,18 +84,20 @@ export async function createProposal(dleAddress, proposalData) { const signer = await provider.getSigner(); // ABI для создания предложения - const dleAbi = [ - "function createProposal(string memory _description, uint256 _duration, bytes memory _operation, uint256 _governanceChainId) external returns (uint256)" + const dleAbi = [ + "function createProposal(string memory _description, uint256 _duration, bytes memory _operation, uint256 _governanceChainId, uint256[] memory _targetChains, uint256 _timelockDelay) external returns (uint256)" ]; const dle = new ethers.Contract(dleAddress, dleAbi, signer); // Создаем предложение - const tx = await dle.createProposal( + const tx = await dle.createProposal( proposalData.description, proposalData.duration, proposalData.operation, - proposalData.governanceChainId + proposalData.governanceChainId, + proposalData.targetChains || [], + proposalData.timelockDelay || 0 ); // Ждем подтверждения транзакции diff --git a/frontend/src/views/settings/DleDeployFormView.vue b/frontend/src/views/settings/DleDeployFormView.vue index 1913f74..439fb1f 100644 --- a/frontend/src/views/settings/DleDeployFormView.vue +++ b/frontend/src/views/settings/DleDeployFormView.vue @@ -683,6 +683,61 @@
💰 Общая стоимость: ~${{ totalDeployCost.toFixed(2) }}
+ + +
+
+ 📍 Предсказанные адреса DLE: +
+ + Адреса вычисляются автоматически при выборе сетей. +
+ + + +
+

🧩 Ключи блокчейн-сканов (опционально для авто-верификации)

+
+
+ +
+ + + +
+
+
+
+ +
@@ -903,6 +958,13 @@ const availableNetworks = ref([]); const isLoadingNetworks = ref(false); const totalDeployCost = ref(0); const predictedAddress = ref(''); +const predictedAddresses = reactive({}); // { chainId: address } +const isPredicting = ref(false); + +// Ключи блокчейн-сканов (локально) +const explorerApiKeys = reactive({}); // { [chainId]: apiKey } +const explorerKeyVisibility = reactive({}); +const persistExplorerKeys = ref(false); // Состояние для приватных ключей const useSameKeyForAllChains = ref(true); @@ -958,6 +1020,61 @@ const hasSelectedNetworks = computed(() => { return selectedNetworks.value.length > 0; }); +// Инициализация полей ключей при смене выбранных сетей +watch(selectedNetworkDetails, (nets) => { + nets.forEach(n => { + if (!(n.chainId in explorerKeyVisibility)) explorerKeyVisibility[n.chainId] = false; + if (persistExplorerKeys.value) { + const saved = localStorage.getItem(`scan_key_${n.chainId}`); + if (saved && !explorerApiKeys[n.chainId]) explorerApiKeys[n.chainId] = saved; + } + }); + if (nets && nets.length > 0) predictAddresses(); +}, { immediate: true }); + +watch(persistExplorerKeys, (val) => { + if (!val) return; + Object.entries(explorerApiKeys).forEach(([chainId, key]) => { + if (key) localStorage.setItem(`scan_key_${chainId}`, key); + }); +}); + +function clearExplorerKeys() { + Object.keys(explorerApiKeys).forEach((k) => explorerApiKeys[k] = ''); + Object.keys(localStorage) + .filter(k => k.startsWith('scan_key_')) + .forEach(k => localStorage.removeItem(k)); +} + +// Предсказание адресов (упрощенно через бэкенд) +async function predictAddresses() { + try { + isPredicting.value = true; + const payload = { + name: dleSettings.name, + symbol: dleSettings.tokenSymbol, + selectedNetworks: selectedNetworkDetails.value.map(n => n.chainId) + }; + const resp = await axios.post('/dle-v2/predict-addresses', payload); + if (resp.data && resp.data.success && resp.data.data) { + // ожидаем вид { [chainId]: address } + Object.keys(predictedAddresses).forEach(k => delete predictedAddresses[k]); + Object.assign(predictedAddresses, resp.data.data); + } + } catch (e) { + console.error('Ошибка расчета предсказанных адресов:', e); + alert('Не удалось рассчитать предсказанные адреса'); + } finally { + isPredicting.value = false; + } +} + +function copyToClipboard(text) { + navigator.clipboard?.writeText(text).then(() => { + // no-op + }).catch(() => {}); +} + // Информация о выбранном стандарте токена const selectedTokenStandardInfo = computed(() => { return tokenStandardsData[dleSettings.tokenStandard] || null; @@ -2306,7 +2423,8 @@ const deploySmartContracts = async () => { currentChainId: dleSettings.selectedNetworks[0] || 1, // Приватный ключ для деплоя - privateKey: unifiedPrivateKey.value + privateKey: unifiedPrivateKey.value, + explorerApiKeys: explorerApiKeys }; console.log('Данные для деплоя DLE:', deployData); @@ -2333,6 +2451,12 @@ const deploySmartContracts = async () => { // Перенаправляем на главную страницу управления router.push('/management'); }, 2000); + if (!persistExplorerKeys.value) { + Object.keys(explorerApiKeys).forEach((k) => explorerApiKeys[k] = ''); + Object.keys(localStorage) + .filter(k => k.startsWith('scan_key_')) + .forEach(k => localStorage.removeItem(k)); + } } else { showDeployProgress.value = false; @@ -2375,6 +2499,15 @@ const validateCoordinates = (coordinates) => {