diff --git a/contracts/ServiceRegistryL2.json b/contracts/ServiceRegistryL2.json new file mode 100644 index 00000000..0054fd27 --- /dev/null +++ b/contracts/ServiceRegistryL2.json @@ -0,0 +1,1899 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ServiceRegistryL2", + "sourceName": "contracts/ServiceRegistryL2.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "AgentInstanceRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "AgentInstancesSlotsFilled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "agentId", + "type": "uint256" + } + ], + "name": "AgentNotFound", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "agentId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "AgentNotInService", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "componentId", + "type": "uint256" + } + ], + "name": "ComponentNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "HashExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "sent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "IncorrectAgentBondingValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "sent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "IncorrectRegistrationDepositValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "ManagerOnly", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "provided", + "type": "address" + }, + { + "internalType": "address", + "name": "expected", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "OnlyOwnServiceMultisig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "OperatorHasNoInstances", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Overflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerOnly", + "type": "error" + }, + { + "inputs": [], + "name": "Paused", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuard", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "ServiceMustBeInactive", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "multisig", + "type": "address" + } + ], + "name": "UnauthorizedMultisig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "agentId", + "type": "uint256" + } + ], + "name": "WrongAgentId", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "numValues1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numValues2", + "type": "uint256" + } + ], + "name": "WrongArrayLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "WrongOperator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "state", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "WrongServiceState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxThreshold", + "type": "uint256" + } + ], + "name": "WrongThreshold", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "ActivateRegistration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "BaseURIChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "multisig", + "type": "address" + } + ], + "name": "CreateMultisigWithAgents", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + } + ], + "name": "CreateService", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "DeployService", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "drainer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Drain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "drainer", + "type": "address" + } + ], + "name": "DrainerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "ManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "OperatorSlashed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "OperatorUnbond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Refund", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "agentInstance", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "agentId", + "type": "uint256" + } + ], + "name": "RegisterInstance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "TerminateService", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + } + ], + "name": "UpdateService", + "type": "event" + }, + { + "inputs": [], + "name": "CID_PREFIX", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "serviceOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "activateRegistration", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDrainer", + "type": "address" + } + ], + "name": "changeDrainer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newManager", + "type": "address" + } + ], + "name": "changeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "multisig", + "type": "address" + }, + { + "internalType": "bool", + "name": "permission", + "type": "bool" + } + ], + "name": "changeMultisigPermission", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "changeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "serviceOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + }, + { + "internalType": "uint32[]", + "name": "agentIds", + "type": "uint32[]" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "slots", + "type": "uint32" + }, + { + "internalType": "uint96", + "name": "bond", + "type": "uint96" + } + ], + "internalType": "struct AgentParams[]", + "name": "agentParams", + "type": "tuple[]" + }, + { + "internalType": "uint32", + "name": "threshold", + "type": "uint32" + } + ], + "name": "create", + "outputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "serviceOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "multisigImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "deploy", + "outputs": [ + { + "internalType": "address", + "name": "multisig", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "drain", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "drainer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "unitId", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "getAgentInstances", + "outputs": [ + { + "internalType": "uint256", + "name": "numAgentInstances", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "agentInstances", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "getAgentParams", + "outputs": [ + { + "internalType": "uint256", + "name": "numAgentIds", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "slots", + "type": "uint32" + }, + { + "internalType": "uint96", + "name": "bond", + "type": "uint96" + } + ], + "internalType": "struct AgentParams[]", + "name": "agentParams", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "agentId", + "type": "uint256" + } + ], + "name": "getInstancesForAgentId", + "outputs": [ + { + "internalType": "uint256", + "name": "numAgentInstances", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "agentInstances", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "getOperatorBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "getPreviousHashes", + "outputs": [ + { + "internalType": "uint256", + "name": "numHashes", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "configHashes", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "getService", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "securityDeposit", + "type": "uint96" + }, + { + "internalType": "address", + "name": "multisig", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "threshold", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxNumAgentInstances", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "numAgentInstances", + "type": "uint32" + }, + { + "internalType": "enum ServiceRegistryL2.ServiceState", + "name": "state", + "type": "uint8" + }, + { + "internalType": "uint32[]", + "name": "agentIds", + "type": "uint32[]" + } + ], + "internalType": "struct ServiceRegistryL2.Service", + "name": "service", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mapAgentInstanceOperators", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapConfigHashes", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mapMultisigs", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapOperatorAndServiceIdAgentInstances", + "outputs": [ + { + "internalType": "address", + "name": "instance", + "type": "address" + }, + { + "internalType": "uint32", + "name": "agentId", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapOperatorAndServiceIdOperatorBalances", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapServiceAndAgentIdAgentInstances", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapServiceAndAgentIdAgentParams", + "outputs": [ + { + "internalType": "uint32", + "name": "slots", + "type": "uint32" + }, + { + "internalType": "uint96", + "name": "bond", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapServices", + "outputs": [ + { + "internalType": "uint96", + "name": "securityDeposit", + "type": "uint96" + }, + { + "internalType": "address", + "name": "multisig", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "threshold", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxNumAgentInstances", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "numAgentInstances", + "type": "uint32" + }, + { + "internalType": "enum ServiceRegistryL2.ServiceState", + "name": "state", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "agentInstances", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "agentIds", + "type": "uint32[]" + } + ], + "name": "registerAgents", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "bURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "agentInstances", + "type": "address[]" + }, + { + "internalType": "uint96[]", + "name": "amounts", + "type": "uint96[]" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "slash", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slashedFunds", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "serviceOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "terminate", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "refund", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "unitId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "unitId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "unbond", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "refund", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "serviceOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "configHash", + "type": "bytes32" + }, + { + "internalType": "uint32[]", + "name": "agentIds", + "type": "uint32[]" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "slots", + "type": "uint32" + }, + { + "internalType": "uint96", + "name": "bond", + "type": "uint96" + } + ], + "internalType": "struct AgentParams[]", + "name": "agentParams", + "type": "tuple[]" + }, + { + "internalType": "uint32", + "name": "threshold", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + } + ], + "name": "update", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60806040526001600a553480156200001657600080fd5b5060405162005bcb38038062005bcb83398101604081905262000039916200014d565b828260006200004983826200026d565b5060016200005882826200026d565b50600891506200006b905082826200026d565b5050600680546001600160a01b0319163317905550620003399050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000b057600080fd5b81516001600160401b0380821115620000cd57620000cd62000088565b604051601f8301601f19908116603f01168101908282118183101715620000f857620000f862000088565b816040528381526020925086838588010111156200011557600080fd5b600091505b838210156200013957858201830151818301840152908201906200011a565b600093810190920192909252949350505050565b6000806000606084860312156200016357600080fd5b83516001600160401b03808211156200017b57600080fd5b62000189878388016200009e565b94506020860151915080821115620001a057600080fd5b620001ae878388016200009e565b93506040860151915080821115620001c557600080fd5b50620001d4868287016200009e565b9150509250925092565b600181811c90821680620001f357607f821691505b6020821081036200021457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200026857600081815260208120601f850160051c81016020861015620002435750805b601f850160051c820191505b8181101562000264578281556001016200024f565b5050505b505050565b81516001600160401b0381111562000289576200028962000088565b620002a1816200029a8454620001de565b846200021a565b602080601f831160018114620002d95760008415620002c05750858301515b600019600386901b1c1916600185901b17855562000264565b600085815260208120601f198616915b828110156200030a57888601518255948401946001909101908401620002e9565b5085821015620003295787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61588280620003496000396000f3fe6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/run_service.sh b/run_service.sh index 7e9e2581..0e9b1824 100755 --- a/run_service.sh +++ b/run_service.sh @@ -62,11 +62,11 @@ ensure_minimum_balance() { local cycle_count=0 while [ "$($PYTHON_CMD -c "print($balance < $minimum_balance)")" == "True" ]; do printf "\r Waiting... ${spin:$i:1} " - i=$(( (i+1) %4 )) + i=$(((i + 1) % 4)) sleep .1 # This will be checked every 10 seconds (100 cycles). - cycle_count=$((cycle_count + 1)) + cycle_count=$((cycle_count + 1)) if [ "$cycle_count" -eq 100 ]; then balance_hex=$(get_balance "$address") balance=$(hex_to_decimal "$balance_hex") @@ -83,6 +83,40 @@ ensure_minimum_balance() { echo "" } +# Get the address from a keys.json file +get_address() { + local keys_json_path="$1" + + if [ ! -f "$keys_json_path" ]; then + echo "Error: $keys_json_path does not exist." + return 1 + fi + + local address_start_position=17 + local address=$(sed -n 3p "$keys_json_path") + address=$(echo "$address" | + awk '{ print substr( $0, '$address_start_position', length($0) - '$address_start_position' - 1 ) }') + + echo -n "$address" +} + +# Get the private key from a keys.json file +get_private_key() { + local keys_json_path="$1" + + if [ ! -f "$keys_json_path" ]; then + echo "Error: $keys_json_path does not exist." + return 1 + fi + + local private_key_start_position=21 + local private_key=$(sed -n 4p "$keys_json_path") + private_key=$(echo -n "$private_key" | + awk '{ printf substr( $0, '$private_key_start_position', length($0) - '$private_key_start_position' ) }') + + echo -n "$private_key" +} + # Function to add a volume to a service in a Docker Compose file add_volume_to_service() { local compose_file="$1" @@ -116,9 +150,11 @@ add_volume_to_service() { # ------------------ set -e # Exit script on first error +echo "" echo "---------------" echo " Trader runner " echo "---------------" +echo "" echo "This script will assist you in setting up and running the Trader service (https://github.com/valory-xyz/trader)." echo "" @@ -220,7 +256,7 @@ fi directory="trader" # This is a tested version that works well. # Feel free to replace this with a different version of the repo, but be careful as there might be breaking changes -service_version="v0.6.3" +service_version="v0.6.4" service_repo=https://github.com/valory-xyz/$directory.git if [ -d $directory ] then @@ -237,6 +273,7 @@ cd $directory if [ "$(git rev-parse --is-inside-work-tree)" = true ] then poetry install + poetry run autonomy packages sync else echo "$directory is not a git repo!" exit 1 @@ -251,6 +288,9 @@ export CUSTOM_CHAIN_ID=$gnosis_chain_id export CUSTOM_SERVICE_MANAGER_ADDRESS="0xE3607b00E75f6405248323A9417ff6b39B244b50" export CUSTOM_SERVICE_REGISTRY_ADDRESS="0x9338b5153AE39BB89f50468E608eD9d764B755fD" export CUSTOM_GNOSIS_SAFE_MULTISIG_ADDRESS="0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE" +export CUSTOM_GNOSIS_SAFE_PROXY_FACTORY_ADDRESS="0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE" +export CUSTOM_GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_ADDRESS="0x3d77596beb0f130a4415df3D2D8232B3d3D31e44" +export CUSTOM_MULTISEND_ADDRESS="0x40A2aCCbd92BCA938b02010E17A5b8929b49130D" if [ "$first_run" = "true" ] then @@ -285,11 +325,8 @@ then echo "" # Check balances - agent_balance=0 - operator_balance=0 suggested_amount=50000000000000000 - - ensure_minimum_balance $operator_address $suggested_amount "operator's address" + ensure_minimum_balance "$operator_address" $suggested_amount "operator's address" echo "Minting your service on the Gnosis chain..." @@ -353,6 +390,162 @@ then echo -n "$service_id" > "../$service_id_path" fi +# Update the on-chain service if required +packages="packages/packages.json" +local_service_hash="$(grep 'service' $packages | awk -F: '{print $2}' | tr -d '", ' | head -n 1)" +remote_service_hash=$(poetry run python "../scripts/service_hash.py") + +if [ "$local_service_hash" != "$remote_service_hash" ]; then + echo "" + echo "Your currently minted on-chain service (id $service_id) mismatches the fetched trader service ($service_version):" + echo " - Local service hash ($service_version): $local_service_hash" + echo " - On-chain service hash (id $service_id): $remote_service_hash" + echo "" + echo "This is most likely caused due to an update of the trader service code." + echo "The script will proceed now to update the on-chain service." + echo "The operator and agent addressess need to have enough funds so that the process is not interrupted." + echo "" + + # Check balances + service_safe_address=$(<"../$service_safe_address_path") + operator_address=$(get_address "../$operator_keys_file") + + suggested_amount=50000000000000000 + ensure_minimum_balance "$operator_address" $suggested_amount "operator's address" + + suggested_amount=50000000000000000 + ensure_minimum_balance $agent_address $suggested_amount "agent instance's address" + + echo "------------------------------" + echo "Updating on-chain service $service_id" + echo "------------------------------" + echo "" + echo "PLEASE, DO NOT INTERRUPT THIS PROCESS." + echo "" + echo "Cancelling the on-chain service update prematurely could lead to an inconsistent state of the Safe or the on-chain service state, which may require manual intervention to resolve." + echo "" + + # generate private key files in the format required by the CLI tool + agent_pkey_file="agent_pkey.txt" + agent_pkey=$(get_private_key "../$keys_json_path") + agent_pkey="${agent_pkey#0x}" + echo -n "$agent_pkey" >"$agent_pkey_file" + + operator_pkey_file="operator_pkey.txt" + operator_pkey=$(get_private_key "../$operator_keys_file") + operator_pkey="${operator_pkey#0x}" + echo -n "$operator_pkey" >"$operator_pkey_file" + + # transfer the ownership of the Safe from the agent to the service owner + # (in a live service, this should be done by sending a 0 DAI transfer to its Safe) + echo "[Agent instance] Swapping Safe owner..." + output=$(poetry run python "../scripts/swap_safe_owner.py" "$service_safe_address" "$agent_pkey_file" "$operator_address" "$rpc") + if [[ $? -ne 0 ]]; then + echo "Swapping Safe owner failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + echo "$output" + + # terminate current service + echo "[Service owner] Terminating on-chain service $service_id..." + output=$( + poetry run autonomy service \ + --use-custom-chain \ + terminate "$service_id" \ + --key "$operator_pkey_file" + ) + if [[ $? -ne 0 ]]; then + echo "Terminating service failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # unbond current service + echo "[Operator] Unbonding on-chain service $service_id..." + output=$( + poetry run autonomy service \ + --use-custom-chain \ + unbond "$service_id" \ + --key "$operator_pkey_file" + ) + if [[ $? -ne 0 ]]; then + echo "Unbonding service failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # update service + echo "[Service owner] Updating on-chain service $service_id..." + agent_id=12 + cost_of_bonding=10000000000000000 + nft="bafybeig64atqaladigoc3ds4arltdu63wkdrk3gesjfvnfdmz35amv7faq" + output=$( + poetry run autonomy mint \ + --skip-hash-check \ + --use-custom-chain \ + service packages/valory/services/trader/ \ + --key "$operator_pkey_file" \ + --nft $nft \ + -a $agent_id \ + -n $n_agents \ + --threshold $n_agents \ + -c $cost_of_bonding \ + --update "$service_id" + ) + if [[ $? -ne 0 ]]; then + echo "Updating service failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # activate service + echo "[Service owner] Activating registration for on-chain service $service_id..." + output=$(poetry run autonomy service --use-custom-chain activate --key "$operator_pkey_file" "$service_id") + if [[ $? -ne 0 ]]; then + echo "Activating service failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # register agent instance + echo "[Operator] Registering agent instance for on-chain service $service_id..." + output=$(poetry run autonomy service --use-custom-chain register --key "$operator_pkey_file" "$service_id" -a $agent_id -i "$agent_address") + if [[ $? -ne 0 ]]; then + echo "Registering agent instance failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # deploy on-chain service + echo "[Service owner] Deploying on-chain service $service_id..." + output=$(poetry run autonomy service --use-custom-chain deploy "$service_id" --key "$operator_pkey_file" --reuse-multisig) + if [[ $? -ne 0 ]]; then + echo "Deploying service failed.\n$output" + rm -f $agent_pkey_file + rm -f $operator_pkey_file + exit 1 + fi + + # delete the pkey files + rm -f $agent_pkey_file + rm -f $operator_pkey_file + echo "" + echo "Finished update of on-chain service $service_id." +fi + +echo "" +echo "------------------------------" +echo "Starting the trader service..." +echo "------------------------------" +echo "" + # check state expected_state="| Service State | DEPLOYED |" service_info=$(poetry run autonomy service --use-custom-chain info "$service_id") @@ -363,8 +556,6 @@ then echo "$service_state" echo "Please check the output of the script for more information." exit 1 -else - echo "$deployment" fi # Get the deployed service's Safe address from the contract @@ -379,12 +570,6 @@ echo "Your agent instance's address: $agent_address" echo "Your service's Safe address: $safe" echo "" -suggested_amount=50000000000000000 -ensure_minimum_balance $agent_address $suggested_amount "agent instance's address" - -suggested_amount=500000000000000000 -ensure_minimum_balance $SAFE_CONTRACT_ADDRESS $suggested_amount "service Safe's address" - # Set environment variables. Tweak these to modify your strategy export RPC_0="$rpc" export CHAIN_ID=$gnosis_chain_id @@ -409,6 +594,13 @@ export REDEEM_MARGIN_DAYS=10 service_dir="trader_service" build_dir="abci_build" directory="$service_dir/$build_dir" + +suggested_amount=50000000000000000 +ensure_minimum_balance $agent_address $suggested_amount "agent instance's address" + +suggested_amount=500000000000000000 +ensure_minimum_balance $SAFE_CONTRACT_ADDRESS $suggested_amount "service Safe's address" + if [ -d $directory ] then echo "Detected an existing build. Using this one..." diff --git a/scripts/service_hash.py b/scripts/service_hash.py new file mode 100644 index 00000000..27b9b8eb --- /dev/null +++ b/scripts/service_hash.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2022-2023 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This script gets the service hash of a specific service on the registry.""" + +import json +from typing import List + +import requests +from web3 import Web3, HTTPProvider + +RPC_PATH = "../.trader_runner/rpc.txt" +SERVICE_ID_PATH = "../.trader_runner/service_id.txt" +REGISTRY_JSON = "../contracts/ServiceRegistryL2.json" +REGISTRY_ADDRESS = "0x9338b5153AE39BB89f50468E608eD9d764B755fD" +AUTONOLAS_GATEWAY = "https://gateway.autonolas.tech/ipfs/" +URI_HASH_POSITION = 7 + + +def _get_hash_from_ipfs(hash_decoded: str) -> str: + """Get the service's `bafybei` hash from IPFS.""" + res = requests.get(f"{AUTONOLAS_GATEWAY}{hash_decoded}") + if res.status_code == 200: + return res.json().get("code_uri", "")[URI_HASH_POSITION:] + raise ValueError(f"Something went wrong while trying to get the code uri from IPFS: {res}") + + +def get_hash() -> str: + """Get the service's hash.""" + contract_data = json.loads(registry_json) + abi = contract_data.get('abi', []) + + w3 = Web3(HTTPProvider(rpc)) + contract_instance = w3.eth.contract(address=REGISTRY_ADDRESS, abi=abi) + hash_encoded = contract_instance.functions.getService(int(service_id)).call()[2] + hash_decoded = f"f01701220{hash_encoded.hex()}" + hash_ = _get_hash_from_ipfs(hash_decoded) + + return hash_ + + +def _parse_args() -> List[str]: + """Parse the RPC and service id.""" + params = [] + for path in (RPC_PATH, SERVICE_ID_PATH, REGISTRY_JSON): + with open(path) as file: + params.append(file.read()) + return params + + +if __name__ == "__main__": + rpc, service_id, registry_json = _parse_args() + print(get_hash()) diff --git a/scripts/swap_safe_owner.py b/scripts/swap_safe_owner.py new file mode 100644 index 00000000..776be63b --- /dev/null +++ b/scripts/swap_safe_owner.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2022-2023 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This script swaps ownership of a Safe with a single owner.""" + +import argparse +import binascii +import sys +import traceback +import typing +from pathlib import Path + +from aea.contracts.base import Contract +from aea_ledger_ethereum.ethereum import EthereumApi, EthereumCrypto +from hexbytes import HexBytes +from web3 import HTTPProvider, Web3 + +from packages.valory.contracts.gnosis_safe.contract import ( + GnosisSafeContract, + SafeOperation, +) +from packages.valory.contracts.multisend.contract import ( + MultiSendContract, + MultiSendOperation, +) +from packages.valory.skills.transaction_settlement_abci.payload_tools import ( + hash_payload_to_hex, + skill_input_hex_to_payload, +) + + +ContractType = typing.TypeVar("ContractType") + + +def load_contract(ctype: ContractType) -> ContractType: + """Load contract.""" + *parts, _ = ctype.__module__.split(".") + path = "/".join(parts) + return Contract.from_dir(directory=path) + + +if __name__ == "__main__": + try: + print(f" - Starting {Path(__file__).name} script...") + + parser = argparse.ArgumentParser( + description="Swap ownership of a Safe with a single owner on the Gnosis chain." + ) + parser.add_argument( + "safe_address", + type=str, + help="Path to the file containing the Ethereum private key", + ) + parser.add_argument( + "current_owner_private_key_path", + type=str, + help="Path to the file containing the Ethereum private key", + ) + parser.add_argument( + "new_owner_address", type=str, help="Recipient address on the Gnosis chain" + ) + parser.add_argument("rpc", type=str, help="RPC for the Gnosis chain") + args = parser.parse_args() + + ledger_api = EthereumApi(address=args.rpc) + current_owner_crypto: EthereumCrypto + current_owner_crypto = EthereumCrypto( + private_key_path=args.current_owner_private_key_path + ) + owner_cryptos: list[EthereumCrypto] = [current_owner_crypto] + + owners = [ + ledger_api.api.to_checksum_address(owner_crypto.address) + for owner_crypto in owner_cryptos + ] + + owner_to_swap = owners[0] + + print(f" - Safe address: {args.safe_address}") + print(f" - Current owner: {owner_to_swap}") + print(f" - New owner: {args.new_owner_address}") + + multisig_address = args.safe_address + multisend_address = "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D" + + print(" - Loading contracts...") + + safe = load_contract(GnosisSafeContract) + multisend = load_contract(MultiSendContract) + + print(" - Building Safe.swapOwner transaction...") + + multisend_txs = [] + + txd = safe.get_swap_owner_data( + ledger_api=ledger_api, + contract_address=multisig_address, + old_owner=ledger_api.api.to_checksum_address(owner_to_swap), + new_owner=ledger_api.api.to_checksum_address(args.new_owner_address), + ).get("data") + multisend_txs.append( + { + "operation": MultiSendOperation.CALL, + "to": multisig_address, + "value": 0, + "data": HexBytes(txd[2:]), + } + ) + + multisend_txd = multisend.get_tx_data( # type: ignore + ledger_api=ledger_api, + contract_address=multisend_address, + multi_send_txs=multisend_txs, + ).get("data") + multisend_data = bytes.fromhex(multisend_txd[2:]) + + safe_tx_hash = safe.get_raw_safe_transaction_hash( + ledger_api=ledger_api, + contract_address=multisig_address, + to_address=multisend_address, + value=0, + data=multisend_data, + safe_tx_gas=0, + operation=SafeOperation.DELEGATE_CALL.value, + ).get("tx_hash")[2:] + + payload_data = hash_payload_to_hex( + safe_tx_hash=safe_tx_hash, + ether_value=0, + safe_tx_gas=0, + to_address=multisend_address, + data=multisend_data, + ) + + tx_params = skill_input_hex_to_payload(payload=payload_data) + safe_tx_bytes = binascii.unhexlify(tx_params["safe_tx_hash"]) + owner_to_signature = {} + + print(" - Signing Safe.swapOwner transaction...") + + for owner_crypto in owner_cryptos: + signature = owner_crypto.sign_message( + message=safe_tx_bytes, + is_deprecated_mode=True, + ) + owner_to_signature[ + ledger_api.api.to_checksum_address(owner_crypto.address) + ] = signature[2:] + + tx = safe.get_raw_safe_transaction( + ledger_api=ledger_api, + contract_address=multisig_address, + sender_address=current_owner_crypto.address, + owners=tuple(owners), # type: ignore + to_address=tx_params["to_address"], + value=tx_params["ether_value"], + data=tx_params["data"], + safe_tx_gas=tx_params["safe_tx_gas"], + signatures_by_owner=owner_to_signature, + operation=SafeOperation.DELEGATE_CALL.value, + ) + stx = current_owner_crypto.sign_transaction(tx) + tx_digest = ledger_api.send_signed_transaction(stx) + + w3 = Web3(HTTPProvider(args.rpc)) + + print(f" - Safe.swapOwner transaction sent. Transaction hash: {tx_digest}") + print(" - Waiting for transaction receipt...") + receipt = w3.eth.wait_for_transaction_receipt(tx_digest) + + if receipt["status"] == 1: + print(" - Safe.swapOwner transaction successfully mined.") + print( + f" - Safe owner successfully swapped from {owner_to_swap} to {args.new_owner_address}" + ) + else: + print(" - Safe.swapOwner transaction failed to be mined.") + sys.exit(1) + + except Exception as e: # pylint: disable=broad-except + print(f"An error occurred while executing {Path(__file__).name}: {str(e)}") + traceback.print_exc() + sys.exit(1)