Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 154 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Register Agents | 21542361 | 24 days ago | IN | 0.001 ETH | 0.00133853 | ||||
Create | 21542272 | 24 days ago | IN | 0 ETH | 0.00157403 | ||||
Deploy | 21395391 | 44 days ago | IN | 0 ETH | 0.01157498 | ||||
Register Agents | 21395353 | 44 days ago | IN | 0.004 ETH | 0.00858576 | ||||
Activate Registr... | 21383684 | 46 days ago | IN | 0.001 ETH | 0.00074555 | ||||
Terminate | 21383679 | 46 days ago | IN | 0 ETH | 0.00100182 | ||||
Activate Registr... | 21383642 | 46 days ago | IN | 0.001 ETH | 0.00070481 | ||||
Activate Registr... | 21383642 | 46 days ago | IN | 0.001 ETH | 0.00070503 | ||||
Activate Registr... | 21383642 | 46 days ago | IN | 0.001 ETH | 0.0007038 | ||||
Activate Registr... | 21383642 | 46 days ago | IN | 0.001 ETH | 0.00075607 | ||||
Update | 21383575 | 46 days ago | IN | 0 ETH | 0.00121886 | ||||
Create | 21383171 | 46 days ago | IN | 0 ETH | 0.00314235 | ||||
Deploy | 21098108 | 86 days ago | IN | 0 ETH | 0.00256991 | ||||
Register Agents | 21098105 | 86 days ago | IN | 0.005 ETH | 0.00082786 | ||||
Activate Registr... | 21098102 | 86 days ago | IN | 0.005 ETH | 0.00021389 | ||||
Create | 21098099 | 86 days ago | IN | 0 ETH | 0.00089379 | ||||
Update | 21088006 | 87 days ago | IN | 0 ETH | 0.00052412 | ||||
Update | 21087914 | 87 days ago | IN | 0 ETH | 0.00061883 | ||||
Update | 21087867 | 87 days ago | IN | 0 ETH | 0.00062697 | ||||
Update | 21087849 | 87 days ago | IN | 0 ETH | 0.00060344 | ||||
Deploy | 21087833 | 87 days ago | IN | 0 ETH | 0.00678291 | ||||
Update | 21085781 | 88 days ago | IN | 0 ETH | 0.00054572 | ||||
Update | 21085757 | 88 days ago | IN | 0 ETH | 0.00056916 | ||||
Update | 21085733 | 88 days ago | IN | 0 ETH | 0.00069009 | ||||
Register Agents | 21084539 | 88 days ago | IN | 0.001 ETH | 0.00199064 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21542361 | 24 days ago | 0.001 ETH | ||||
21542348 | 24 days ago | 0.001 ETH | ||||
21542348 | 24 days ago | 0.001 ETH | ||||
21395353 | 44 days ago | 0.004 ETH | ||||
21383684 | 46 days ago | 0.001 ETH | ||||
21383642 | 46 days ago | 0.001 ETH | ||||
21383642 | 46 days ago | 0.001 ETH | ||||
21383642 | 46 days ago | 0.001 ETH | ||||
21383642 | 46 days ago | 0.001 ETH | ||||
21170419 | 76 days ago | 1 wei | ||||
21170419 | 76 days ago | 1 wei | ||||
21170417 | 76 days ago | 1 wei | ||||
21170417 | 76 days ago | 1 wei | ||||
21123394 | 82 days ago | 1 wei | ||||
21123394 | 82 days ago | 1 wei | ||||
21123393 | 82 days ago | 1 wei | ||||
21123393 | 82 days ago | 1 wei | ||||
21122096 | 83 days ago | 1 wei | ||||
21122096 | 83 days ago | 1 wei | ||||
21122094 | 83 days ago | 1 wei | ||||
21122094 | 83 days ago | 1 wei | ||||
21098105 | 86 days ago | 0.005 ETH | ||||
21098102 | 86 days ago | 0.005 ETH | ||||
21084539 | 88 days ago | 0.001 ETH | ||||
21078982 | 89 days ago | 0.001 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ServiceManagerToken
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 750 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {GenericManager} from "./GenericManager.sol"; import {OperatorSignedHashes} from "./utils/OperatorSignedHashes.sol"; import "./interfaces/IService.sol"; import "./interfaces/IServiceTokenUtility.sol"; // Operator whitelist interface interface IOperatorWhitelist { /// @dev Gets operator whitelisting status. /// @param serviceId Service Id. /// @param operator Operator address. /// @return status Whitelisting status. function isOperatorWhitelisted(uint256 serviceId, address operator) external view returns (bool status); } // Generic token interface interface IToken { /// @dev Gets the owner of the token Id. /// @param tokenId Token Id. /// @return Token Id owner address. function ownerOf(uint256 tokenId) external view returns (address); } /// @title Service Manager - Periphery smart contract for managing services with custom ERC20 tokens or ETH /// @author Aleksandr Kuperman - <[email protected]> /// @author AL contract ServiceManagerToken is GenericManager, OperatorSignedHashes { event OperatorWhitelistUpdated(address indexed operatorWhitelist); event CreateMultisig(address indexed multisig); // Service Registry address address public immutable serviceRegistry; // Service Registry Token Utility address address public immutable serviceRegistryTokenUtility; // A well-known representation of ETH as an address address public constant ETH_TOKEN_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); // Bond wrapping constant uint96 public constant BOND_WRAPPER = 1; // Operator whitelist address address public operatorWhitelist; /// @dev ServiceRegistryTokenUtility constructor. /// @param _serviceRegistry Service Registry contract address. /// @param _serviceRegistryTokenUtility Service Registry Token Utility contract address. constructor(address _serviceRegistry, address _serviceRegistryTokenUtility, address _operatorWhitelist) OperatorSignedHashes("Service Manager Token", "1.1.1") { // Check for the Service Registry related contract zero addresses if (_serviceRegistry == address(0) || _serviceRegistryTokenUtility == address(0)) { revert ZeroAddress(); } serviceRegistry = _serviceRegistry; serviceRegistryTokenUtility = _serviceRegistryTokenUtility; operatorWhitelist = _operatorWhitelist; owner = msg.sender; } /// @dev Sets the operator whitelist contract address. /// @param newOperatorWhitelist New operator whitelist contract address. function setOperatorWhitelist(address newOperatorWhitelist) external { // Check for the contract ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); } operatorWhitelist = newOperatorWhitelist; emit OperatorWhitelistUpdated(newOperatorWhitelist); } /// @dev Creates a new service. /// @param serviceOwner Individual that creates and controls a service. /// @param token ERC20 token address for the security deposit, or ETH. /// @param configHash IPFS hash pointing to the config metadata. /// @param agentIds Canonical agent Ids. /// @param agentParams Number of agent instances and required bond to register an instance in the service. /// @param threshold Threshold for a multisig composed by agents. /// @return serviceId Created service Id. function create( address serviceOwner, address token, bytes32 configHash, uint32[] memory agentIds, IService.AgentParams[] memory agentParams, uint32 threshold ) external returns (uint256 serviceId) { // Check if the minting is paused if (paused) { revert Paused(); } // Check for the zero address if (token == address(0)) { revert ZeroAddress(); } // Check for the custom ERC20 token or ETH based bond if (token == ETH_TOKEN_ADDRESS) { // Call the original ServiceRegistry contract function serviceId = IService(serviceRegistry).create(serviceOwner, configHash, agentIds, agentParams, threshold); } else { // Wrap agent params with just 1 WEI bond going to the original ServiceRegistry contract, // and actual token bonds being recorded with the ServiceRegistryTokenUtility contract uint256 numAgents = agentParams.length; uint256[] memory bonds = new uint256[](numAgents); for (uint256 i = 0; i < numAgents; ++i) { // Check for the zero bond value if (agentParams[i].bond == 0) { revert ZeroValue(); } // Copy actual bond values for each agent Id bonds[i] = agentParams[i].bond; // Wrap bonds with the BOND_WRAPPER value for the original ServiceRegistry contract agentParams[i].bond = BOND_WRAPPER; } // Call the original ServiceRegistry contract function serviceId = IService(serviceRegistry).create(serviceOwner, configHash, agentIds, agentParams, threshold); // Create a token-related record for the service IServiceTokenUtility(serviceRegistryTokenUtility).createWithToken(serviceId, token, agentIds, bonds); } } /// @dev Updates a service in a CRUD way. /// @param token ERC20 token address for the security deposit, or ETH. /// @param configHash IPFS hash pointing to the config metadata. /// @param agentIds Canonical agent Ids. /// @param agentParams Number of agent instances and required bond to register an instance in the service. /// @param threshold Threshold for a multisig composed by agents. /// @param serviceId Service Id to be updated. /// @return success True, if function executed successfully. function update( address token, bytes32 configHash, uint32[] memory agentIds, IService.AgentParams[] memory agentParams, uint32 threshold, uint256 serviceId ) external returns (bool success) { // Check for the zero address if (token == address(0)) { revert ZeroAddress(); } uint256 numAgents = agentParams.length; if (token == ETH_TOKEN_ADDRESS) { // If any of the slots is a non-zero, the correspondent bond cannot be zero for (uint256 i = 0; i < numAgents; ++i) { // Check for the zero bond value if (agentParams[i].slots > 0 && agentParams[i].bond == 0) { revert ZeroValue(); } } // Call the original ServiceRegistry contract function success = IService(serviceRegistry).update(msg.sender, configHash, agentIds, agentParams, threshold, serviceId); // Reset the service token-based data // This function still needs to be called as the previous token could be a custom ERC20 token IServiceTokenUtility(serviceRegistryTokenUtility).resetServiceToken(serviceId); } else { // Wrap agent params with just 1 WEI bond going to the original ServiceRegistry contract, // and actual token bonds being recorded with the ServiceRegistryTokenUtility contract uint256[] memory bonds = new uint256[](numAgents); for (uint256 i = 0; i < numAgents; ++i) { // Copy actual bond values for each agent Id that has at least one slot in the updated service if (agentParams[i].slots > 0) { // Check for the zero bond value if (agentParams[i].bond == 0) { revert ZeroValue(); } bonds[i] = agentParams[i].bond; // Wrap bonds with the BOND_WRAPPER value for the original ServiceRegistry contract agentParams[i].bond = BOND_WRAPPER; } } // Call the original ServiceRegistry contract function success = IService(serviceRegistry).update(msg.sender, configHash, agentIds, agentParams, threshold, serviceId); // Update relevant data in the ServiceRegistryTokenUtility contract // We follow the optimistic design where existing bonds are just overwritten without a clearing // bond values of agent Ids that are not going to be used in the service. This is coming from the fact // that all the checks are done on the original ServiceRegistry side IServiceTokenUtility(serviceRegistryTokenUtility).createWithToken(serviceId, token, agentIds, bonds); } } /// @dev Activates the service and its sensitive components. /// @param serviceId Correspondent service Id. /// @return success True, if function executed successfully. function activateRegistration(uint256 serviceId) external payable returns (bool success) { // Record the actual ERC20 security deposit bool isTokenSecured = IServiceTokenUtility(serviceRegistryTokenUtility).activateRegistrationTokenDeposit(serviceId); // Activate registration in the original ServiceRegistry contract if (isTokenSecured) { // If the service Id is based on the ERC20 token, the provided value to the standard registration is 1 success = IService(serviceRegistry).activateRegistration{value: BOND_WRAPPER}(msg.sender, serviceId); } else { // Otherwise follow the standard msg.value path success = IService(serviceRegistry).activateRegistration{value: msg.value}(msg.sender, serviceId); } } /// @dev Registers agent instances. /// @param serviceId Service Id to be updated. /// @param agentInstances Agent instance addresses. /// @param agentIds Canonical Ids of the agent correspondent to the agent instance. /// @return success True, if function executed successfully. function registerAgents( uint256 serviceId, address[] memory agentInstances, uint32[] memory agentIds ) external payable returns (bool success) { if (operatorWhitelist != address(0)) { // Check if the operator is whitelisted if (!IOperatorWhitelist(operatorWhitelist).isOperatorWhitelisted(serviceId, msg.sender)) { revert WrongOperator(serviceId); } } // Record the actual ERC20 bond bool isTokenSecured = IServiceTokenUtility(serviceRegistryTokenUtility).registerAgentsTokenDeposit(msg.sender, serviceId, agentIds); // Register agent instances in a main ServiceRegistry contract if (isTokenSecured) { // If the service Id is based on the ERC20 token, the provided value to the standard registration is 1 // multiplied by the number of agent instances success = IService(serviceRegistry).registerAgents{value: agentInstances.length * BOND_WRAPPER}(msg.sender, serviceId, agentInstances, agentIds); } else { // Otherwise follow the standard msg.value path success = IService(serviceRegistry).registerAgents{value: msg.value}(msg.sender, serviceId, agentInstances, agentIds); } } /// @dev Creates multisig instance controlled by the set of service agent instances and deploys the service. /// @param serviceId Correspondent service Id. /// @param multisigImplementation Multisig implementation address. /// @param data Data payload for the multisig creation. /// @return multisig Address of the created multisig. function deploy( uint256 serviceId, address multisigImplementation, bytes memory data ) external returns (address multisig) { multisig = IService(serviceRegistry).deploy(msg.sender, serviceId, multisigImplementation, data); emit CreateMultisig(multisig); } /// @dev Terminates the service. /// @param serviceId Service Id. /// @return success True, if function executed successfully. /// @return refund Refund for the service owner. function terminate(uint256 serviceId) external returns (bool success, uint256 refund) { // Withdraw the ERC20 token if the service is token-based uint256 tokenRefund = IServiceTokenUtility(serviceRegistryTokenUtility).terminateTokenRefund(serviceId); // Terminate the service with the regular service registry routine (success, refund) = IService(serviceRegistry).terminate(msg.sender, serviceId); // If the service is token-based, the actual refund is provided via the serviceRegistryTokenUtility contract if (tokenRefund > 0) { refund = tokenRefund; } } /// @dev Unbonds agent instances of the operator from the service. /// @param serviceId Service Id. /// @return success True, if function executed successfully. /// @return refund The amount of refund returned to the operator. function unbond(uint256 serviceId) external returns (bool success, uint256 refund) { // Withdraw the ERC20 token if the service is token-based uint256 tokenRefund = IServiceTokenUtility(serviceRegistryTokenUtility).unbondTokenRefund(msg.sender, serviceId); // Unbond with the regular service registry routine (success, refund) = IService(serviceRegistry).unbond(msg.sender, serviceId); // If the service is token-based, the actual refund is provided via the serviceRegistryTokenUtility contract if (tokenRefund > 0) { refund = tokenRefund; } } /// @dev Unbonds agent instances of the operator by the service owner via the operator's pre-signed message hash. /// @notice Note that this function accounts for the operator being the EOA, or the contract that has an /// isValidSignature() function that would confirm the message hash was signed by the operator contract. /// Otherwise, if the message hash has been pre-approved, the corresponding map of hashes is going to /// to verify the signed hash, similar to the Safe contract implementation in v1.3.0: /// https://github.com/safe-global/safe-contracts/blob/186a21a74b327f17fc41217a927dea7064f74604/contracts/GnosisSafe.sol#L240-L304 /// Also note that only the service owner is able to call this function on behalf of the operator. /// @param operator Operator address that signed the unbond message hash. /// @param serviceId Service Id. /// @param signature Signature byte array associated with operator message hash signature. /// @return success True, if the function executed successfully. /// @return refund The amount of refund returned to the operator. function unbondWithSignature( address operator, uint256 serviceId, bytes memory signature ) external returns (bool success, uint256 refund) { // Check the service owner address serviceOwner = IToken(serviceRegistry).ownerOf(serviceId); if (msg.sender != serviceOwner) { revert OwnerOnly(msg.sender, serviceOwner); } // Get the (operator | serviceId) nonce for the unbond message // Push a pair of key defining variables into one key. Service Id or operator are not enough by themselves // as another service might use the operator address at the same time frame // operator occupies first 160 bits uint256 operatorService = uint256(uint160(operator)); // serviceId occupies next 32 bits operatorService |= serviceId << 160; uint256 nonce = mapOperatorUnbondNonces[operatorService]; // Get the unbond message hash bytes32 msgHash = getUnbondHash(operator, serviceOwner, serviceId, nonce); // Verify the signed hash against the operator address _verifySignedHash(operator, msgHash, signature); // Update corresponding nonce value nonce++; mapOperatorUnbondNonces[operatorService] = nonce; // Withdraw the ERC20 token if the service is token-based uint256 tokenRefund = IServiceTokenUtility(serviceRegistryTokenUtility).unbondTokenRefund(operator, serviceId); // Unbond with the regular service registry routine (success, refund) = IService(serviceRegistry).unbond(operator, serviceId); // If the service is token-based, the actual refund is provided via the serviceRegistryTokenUtility contract if (tokenRefund > 0) { refund = tokenRefund; } } /// @dev Registers agent instances of the operator by the service owner via the operator's pre-signed message hash. /// @notice Note that this function accounts for the operator being the EOA, or the contract that has an /// isValidSignature() function that would confirm the message hash was signed by the operator contract. /// Otherwise, if the message hash has been pre-approved, the corresponding map of hashes is going to /// to verify the signed hash, similar to the Safe contract implementation in v1.3.0: /// https://github.com/safe-global/safe-contracts/blob/186a21a74b327f17fc41217a927dea7064f74604/contracts/GnosisSafe.sol#L240-L304 /// Also note that only the service owner is able to call this function on behalf of the operator. /// @param operator Operator address that signed the register agents message hash. /// @param serviceId Service Id. /// @param agentInstances Agent instance addresses. /// @param agentIds Canonical Ids of the agent correspondent to the agent instance. /// @param signature Signature byte array associated with operator message hash signature. /// @return success True, if the the function executed successfully. function registerAgentsWithSignature( address operator, uint256 serviceId, address[] memory agentInstances, uint32[] memory agentIds, bytes memory signature ) external payable returns (bool success) { // Check the service owner address serviceOwner = IToken(serviceRegistry).ownerOf(serviceId); if (msg.sender != serviceOwner) { revert OwnerOnly(msg.sender, serviceOwner); } // Get the (operator | serviceId) nonce for the registerAgents message // Push a pair of key defining variables into one key. Service Id or operator are not enough by themselves // as another service might use the operator address at the same time frame // operator occupies first 160 bits uint256 operatorService = uint256(uint160(operator)); // serviceId occupies next 32 bits as serviceId is limited by the 2^32 - 1 value operatorService |= serviceId << 160; uint256 nonce = mapOperatorRegisterAgentsNonces[operatorService]; // Get register agents message hash bytes32 msgHash = getRegisterAgentsHash(operator, serviceOwner, serviceId, agentInstances, agentIds, nonce); // Verify the signed hash against the operator address _verifySignedHash(operator, msgHash, signature); // Update corresponding nonce value nonce++; mapOperatorRegisterAgentsNonces[operatorService] = nonce; // Record the actual ERC20 bond bool isTokenSecured = IServiceTokenUtility(serviceRegistryTokenUtility).registerAgentsTokenDeposit(operator, serviceId, agentIds); // Register agent instances in a main ServiceRegistry contract if (isTokenSecured) { // If the service Id is based on the ERC20 token, the provided value to the standard registration is 1 // multiplied by the number of agent instances success = IService(serviceRegistry).registerAgents{value: agentInstances.length * BOND_WRAPPER}(operator, serviceId, agentInstances, agentIds); } else { // Otherwise follow the standard msg.value path success = IService(serviceRegistry).registerAgents{value: msg.value}(operator, serviceId, agentInstances, agentIds); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "./interfaces/IErrorsRegistries.sol"; /// @title Generic Manager - Smart contract for generic registry manager template /// @author Aleksandr Kuperman - <[email protected]> abstract contract GenericManager is IErrorsRegistries { event OwnerUpdated(address indexed owner); event Pause(address indexed owner); event Unpause(address indexed owner); // Owner address address public owner; // Pause switch bool public paused; /// @dev Changes the owner address. /// @param newOwner Address of a new owner. function changeOwner(address newOwner) external virtual { // Check for the ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); } // Check for the zero address if (newOwner == address(0)) { revert ZeroAddress(); } owner = newOwner; emit OwnerUpdated(newOwner); } /// @dev Pauses the contract. function pause() external virtual { // Check for the ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); } paused = true; emit Pause(msg.sender); } /// @dev Unpauses the contract. function unpause() external virtual { // Check for the ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); } paused = false; emit Unpause(msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; /// @dev Errors. interface IErrorsRegistries { /// @dev Only `manager` has a privilege, but the `sender` was provided. /// @param sender Sender address. /// @param manager Required sender address as a manager. error ManagerOnly(address sender, address manager); /// @dev Only `owner` has a privilege, but the `sender` was provided. /// @param sender Sender address. /// @param owner Required sender address as an owner. error OwnerOnly(address sender, address owner); /// @dev Hash already exists in the records. error HashExists(); /// @dev Provided zero address. error ZeroAddress(); /// @dev Agent Id is not correctly provided for the current routine. /// @param agentId Component Id. error WrongAgentId(uint256 agentId); /// @dev Wrong length of two arrays. /// @param numValues1 Number of values in a first array. /// @param numValues2 Numberf of values in a second array. error WrongArrayLength(uint256 numValues1, uint256 numValues2); /// @dev Canonical agent Id is not found. /// @param agentId Canonical agent Id. error AgentNotFound(uint256 agentId); /// @dev Component Id is not found. /// @param componentId Component Id. error ComponentNotFound(uint256 componentId); /// @dev Multisig threshold is out of bounds. /// @param currentThreshold Current threshold value. /// @param minThreshold Minimum possible threshold value. /// @param maxThreshold Maximum possible threshold value. error WrongThreshold(uint256 currentThreshold, uint256 minThreshold, uint256 maxThreshold); /// @dev Agent instance is already registered with a specified `operator`. /// @param operator Operator that registered an instance. error AgentInstanceRegistered(address operator); /// @dev Wrong operator is specified when interacting with a specified `serviceId`. /// @param serviceId Service Id. error WrongOperator(uint256 serviceId); /// @dev Operator has no registered instances in the service. /// @param operator Operator address. /// @param serviceId Service Id. error OperatorHasNoInstances(address operator, uint256 serviceId); /// @dev Canonical `agentId` is not found as a part of `serviceId`. /// @param agentId Canonical agent Id. /// @param serviceId Service Id. error AgentNotInService(uint256 agentId, uint256 serviceId); /// @dev The contract is paused. error Paused(); /// @dev Zero value when it has to be different from zero. error ZeroValue(); /// @dev Value overflow. /// @param provided Overflow value. /// @param max Maximum possible value. error Overflow(uint256 provided, uint256 max); /// @dev Service must be inactive. /// @param serviceId Service Id. error ServiceMustBeInactive(uint256 serviceId); /// @dev All the agent instance slots for a specific `serviceId` are filled. /// @param serviceId Service Id. error AgentInstancesSlotsFilled(uint256 serviceId); /// @dev Wrong state of a service. /// @param state Service state. /// @param serviceId Service Id. error WrongServiceState(uint256 state, uint256 serviceId); /// @dev Only own service multisig is allowed. /// @param provided Provided address. /// @param expected Expected multisig address. /// @param serviceId Service Id. error OnlyOwnServiceMultisig(address provided, address expected, uint256 serviceId); /// @dev Multisig is not whitelisted. /// @param multisig Address of a multisig implementation. error UnauthorizedMultisig(address multisig); /// @dev Incorrect deposit provided for the registration activation. /// @param sent Sent amount. /// @param expected Expected amount. /// @param serviceId Service Id. error IncorrectRegistrationDepositValue(uint256 sent, uint256 expected, uint256 serviceId); /// @dev Insufficient value provided for the agent instance bonding. /// @param sent Sent amount. /// @param expected Expected amount. /// @param serviceId Service Id. error IncorrectAgentBondingValue(uint256 sent, uint256 expected, uint256 serviceId); /// @dev Failure of a transfer. /// @param token Address of a token. /// @param from Address `from`. /// @param to Address `to`. /// @param value Value. error TransferFailed(address token, address from, address to, uint256 value); /// @dev Caught reentrancy violation. error ReentrancyGuard(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; /// @dev Required interface for the service manipulation. interface IService{ struct AgentParams { // Number of agent instances uint32 slots; // Bond per agent instance uint96 bond; } /// @dev Creates a new service. /// @param serviceOwner Individual that creates and controls a service. /// @param configHash IPFS hash pointing to the config metadata. /// @param agentIds Canonical agent Ids in a sorted ascending order. /// @param agentParams Number of agent instances and required bond to register an instance in the service. /// @param threshold Signers threshold for a multisig composed by agent instances. /// @return serviceId Created service Id. function create( address serviceOwner, bytes32 configHash, uint32[] memory agentIds, AgentParams[] memory agentParams, uint32 threshold ) external returns (uint256 serviceId); /// @dev Updates a service in a CRUD way. /// @param serviceOwner Individual that creates and controls a service. /// @param configHash IPFS hash pointing to the config metadata. /// @param agentIds Canonical agent Ids in a sorted ascending order. /// @param agentParams Number of agent instances and required bond to register an instance in the service. /// @param threshold Signers threshold for a multisig composed by agent instances. /// @param serviceId Service Id to be updated. /// @return success True, if function executed successfully. function update( address serviceOwner, bytes32 configHash, uint32[] memory agentIds, AgentParams[] memory agentParams, uint32 threshold, uint256 serviceId ) external returns (bool success); /// @dev Activates the service. /// @param serviceOwner Individual that creates and controls a service. /// @param serviceId Correspondent service Id. /// @return success True, if function executed successfully. function activateRegistration(address serviceOwner, uint256 serviceId) external payable returns (bool success); /// @dev Registers agent instances. /// @param operator Address of the operator. /// @param serviceId Service Id to be updated. /// @param agentInstances Agent instance addresses. /// @param agentIds Canonical Ids of the agent correspondent to the agent instance. /// @return success True, if function executed successfully. function registerAgents( address operator, uint256 serviceId, address[] memory agentInstances, uint32[] memory agentIds ) external payable returns (bool success); /// @dev Creates multisig instance controlled by the set of service agent instances and deploys the service. /// @param serviceOwner Individual that creates and controls a service. /// @param serviceId Correspondent service Id. /// @param multisigImplementation Multisig implementation address. /// @param data Data payload for the multisig creation. /// @return multisig Address of the created multisig. function deploy( address serviceOwner, uint256 serviceId, address multisigImplementation, bytes memory data ) external returns (address multisig); /// @dev Terminates the service. /// @param serviceOwner Owner of the service. /// @param serviceId Service Id to be updated. /// @return success True, if function executed successfully. /// @return refund Refund to return to the serviceOwner. function terminate(address serviceOwner, uint256 serviceId) external returns (bool success, uint256 refund); /// @dev Unbonds agent instances of the operator from the service. /// @param operator Operator of agent instances. /// @param serviceId Service Id. /// @return success True, if function executed successfully. /// @return refund The amount of refund returned to the operator. function unbond(address operator, uint256 serviceId) external returns (bool success, uint256 refund); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /// @dev Interface for the service registration token utility manipulation. interface IServiceTokenUtility { /// @dev Creates a record with the token-related information for the specified service. /// @param serviceId Service Id. /// @param token Token address. /// @param agentIds Set of agent Ids. /// @param bonds Set of correspondent bonds. function createWithToken( uint256 serviceId, address token, uint32[] memory agentIds, uint256[] memory bonds ) external; /// @dev Resets a record with token and security deposit data. /// @param serviceId Service Id. function resetServiceToken(uint256 serviceId) external; /// @dev Deposit a token security deposit for the service registration after its activation. /// @param serviceId Service Id. /// @return isTokenSecured True if the service Id is token secured, false if ETH secured otherwise. function activateRegistrationTokenDeposit(uint256 serviceId) external returns (bool isTokenSecured); /// @dev Deposits bonded tokens from the operator during the agent instance registration. /// @param operator Operator address. /// @param serviceId Service Id. /// @param agentIds Set of agent Ids for corresponding agent instances opertor is registering. /// @return isTokenSecured True if the service Id is token secured, false if ETH secured otherwise. function registerAgentsTokenDeposit( address operator, uint256 serviceId, uint32[] memory agentIds ) external returns (bool isTokenSecured); /// @dev Withdraws a token security deposit to the service owner after the service termination. /// @param serviceId Service Id. /// @return securityRefund Returned token security deposit, or zero if the service is ETH-secured. function terminateTokenRefund(uint256 serviceId) external returns (uint256 securityRefund); /// @dev Withdraws bonded tokens to the operator during the unbond phase. /// @param operator Operator address. /// @param serviceId Service Id. /// @return refund Returned bonded token amount, or zero if the service is ETH-secured. function unbondTokenRefund(address operator, uint256 serviceId) external returns (uint256 refund); /// @dev Gets service token secured status. /// @param serviceId Service Id. /// @return True if the service Id is token secured. function isTokenSecuredService(uint256 serviceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface ISignatureValidator { /// @dev Should return whether the signature provided is valid for the provided hash. /// @notice MUST return the bytes4 magic value 0x1626ba7e when function passes. /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5). /// MUST allow external calls. /// @param hash Hash of the data to be signed. /// @param signature Signature byte array associated with hash. /// @return magicValue bytes4 magic value. function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); } /// @dev Provided zero address. error ZeroOperatorAddress(); /// @dev Incorrect signature length provided. /// @param signature Signature bytes. /// @param provided Provided signature length. /// @param expected Expected signature length. error IncorrectSignatureLength(bytes signature, uint256 provided, uint256 expected); /// @dev Hash is not validated. /// @param operator Operator contract address. /// @param msgHash Message hash. /// @param signature Signature bytes associated with the message hash. error HashNotValidated(address operator, bytes32 msgHash, bytes signature); /// @dev Hash is not approved. /// @param operator Operator address. /// @param msgHash Message hash. /// @param signature Signature bytes associated with the message hash. error HashNotApproved(address operator, bytes32 msgHash, bytes signature); /// @dev Obtained wrong operator address. /// @param provided Provided address. /// @param expected Expected address. error WrongOperatorAddress(address provided, address expected); /// @title OperatorSignedHashes - Smart contract for managing operator signed hashes /// @author AL /// @author Aleksandr Kuperman - <[email protected]> contract OperatorSignedHashes { event OperatorHashApproved(address indexed operator, bytes32 hash); // Value for the contract signature validation: bytes4(keccak256("isValidSignature(bytes32,bytes)") bytes4 constant internal MAGIC_VALUE = 0x1626ba7e; // Domain separator type hash bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Unbond type hash bytes32 public constant UNBOND_TYPE_HASH = keccak256("Unbond(address operator,address serviceOwner,uint256 serviceId,uint256 nonce)"); // Register agents type hash bytes32 public constant REGISTER_AGENTS_TYPE_HASH = keccak256("RegisterAgents(address operator,address serviceOwner,uint256 serviceId,bytes32 agentsData,uint256 nonce)"); // Original domain separator value bytes32 public immutable domainSeparator; // Original chain Id uint256 public immutable chainId; // Name hash bytes32 public immutable nameHash; // Version hash bytes32 public immutable versionHash; // Name of a signing domain string public name; // Version of a signing domain string public version; // Map of operator address and serviceId => unbond nonce mapping(uint256 => uint256) public mapOperatorUnbondNonces; // Map of operator address and serviceId => register agents nonce mapping(uint256 => uint256) public mapOperatorRegisterAgentsNonces; // Mapping operator address => approved hashes status mapping(address => mapping(bytes32 => bool)) public mapOperatorApprovedHashes; /// @dev Contract constructor. /// @param _name Name of a signing domain. /// @param _version Version of a signing domain. constructor(string memory _name, string memory _version) { name = _name; version = _version; nameHash = keccak256(bytes(_name)); versionHash = keccak256(bytes(_version)); chainId = block.chainid; domainSeparator = _computeDomainSeparator(); } /// @dev Verifies provided message hash against its signature. /// @param operator Operator address. /// @param msgHash Message hash. /// @param signature Signature bytes associated with the signed message hash. function _verifySignedHash(address operator, bytes32 msgHash, bytes memory signature) internal view { // Check for the operator zero address if (operator == address(0)) { revert ZeroOperatorAddress(); } // Check for the signature length if (signature.length != 65) { revert IncorrectSignatureLength(signature, signature.length, 65); } // Decode the signature uint8 v = uint8(signature[64]); // For the correct ecrecover() function execution, the v value must be set to {0,1} + 27 // Although v in a very rare case can be equal to {2,3} (with a probability of 3.73e-37%) // If v is set to just 0 or 1 when signing by the EOA, it is most likely signed by the ledger and must be adjusted if (v < 4 && operator.code.length == 0) { // In case of a non-contract, adjust v to follow the standard ecrecover case v += 27; } bytes32 r; bytes32 s; // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 32)) s := mload(add(signature, 64)) } address recOperator; // Go through signature cases based on the value of v if (v == 4) { // Contract signature case, where the address of the contract is encoded into r recOperator = address(uint160(uint256(r))); // Check for the signature validity in the contract if (ISignatureValidator(recOperator).isValidSignature(msgHash, signature) != MAGIC_VALUE) { revert HashNotValidated(recOperator, msgHash, signature); } } else if (v == 5) { // Case of an approved hash, where the address of the operator is encoded into r recOperator = address(uint160(uint256(r))); // Hashes have been pre-approved by the operator via a separate message, see operatorApproveHash() function if (!mapOperatorApprovedHashes[recOperator][msgHash]) { revert HashNotApproved(recOperator, msgHash, signature); } } else { // Case of ecrecover with the message hash for EOA signatures recOperator = ecrecover(msgHash, v, r, s); } // Final check is for the operator address itself if (recOperator != operator) { revert WrongOperatorAddress(recOperator, operator); } } /// @dev Approves message hash for the operator address. /// @param hash Provided message hash to approve. function operatorApproveHash(bytes32 hash) external { mapOperatorApprovedHashes[msg.sender][hash] = true; emit OperatorHashApproved(msg.sender, hash); } /// @dev Computes domain separator hash. /// @return Hash of the domain separator based on its name, version, chain Id and contract address. function _computeDomainSeparator() internal view returns (bytes32) { return keccak256( abi.encode( DOMAIN_SEPARATOR_TYPE_HASH, nameHash, versionHash, block.chainid, address(this) ) ); } /// @dev Gets the already computed domain separator of recomputes one if the chain Id is different. /// @return Original or recomputed domain separator. function getDomainSeparator() public view returns (bytes32) { return block.chainid == chainId ? domainSeparator : _computeDomainSeparator(); } /// @dev Gets the unbond message hash for the operator. /// @param operator Operator address. /// @param serviceOwner Service owner address. /// @param serviceId Service Id. /// @param nonce Nonce for the unbond message from the pair of (operator | service Id). /// @return Computed message hash. function getUnbondHash( address operator, address serviceOwner, uint256 serviceId, uint256 nonce ) public view returns (bytes32) { return keccak256( abi.encodePacked( "\x19\x01", getDomainSeparator(), keccak256( abi.encode( UNBOND_TYPE_HASH, operator, serviceOwner, serviceId, nonce ) ) ) ); } /// @dev Gets the register agents message hash for the operator. /// @param operator Operator address. /// @param serviceOwner Service owner address. /// @param serviceId Service Id. /// @param agentInstances Agent instance addresses operator is going to register. /// @param agentIds Agent Ids corresponding to each agent instance address. /// @param nonce Nonce for the register agents message from the pair of (operator | service Id). /// @return Computed message hash. function getRegisterAgentsHash( address operator, address serviceOwner, uint256 serviceId, address[] memory agentInstances, uint32[] memory agentIds, uint256 nonce ) public view returns (bytes32) { return keccak256( abi.encodePacked( "\x19\x01", getDomainSeparator(), keccak256( abi.encode( REGISTER_AGENTS_TYPE_HASH, operator, serviceOwner, serviceId, keccak256(abi.encode(agentInstances, agentIds)), nonce ) ) ) ); } /// @dev Checks if the hash provided by the operator is approved. /// @param operator Operator address. /// @param hash Message hash. /// @return True, if the hash provided by the operator is approved. function isOperatorHashApproved(address operator, bytes32 hash) external view returns (bool) { return mapOperatorApprovedHashes[operator][hash]; } /// @dev Gets the (operator | service Id) nonce for the unbond message data. /// @param operator Operator address. /// @param serviceId Service Id. /// @return nonce Obtained nonce. function getOperatorUnbondNonce(address operator, uint256 serviceId) external view returns (uint256 nonce) { // operator occupies first 160 bits uint256 operatorService = uint256(uint160(operator)); // serviceId occupies next 32 bits as serviceId is limited by the 2^32 - 1 value operatorService |= serviceId << 160; nonce = mapOperatorUnbondNonces[operatorService]; } /// @dev Gets the (operator | service Id) nonce for the register agents message data. /// @param operator Operator address. /// @param serviceId Service Id. /// @return nonce Obtained nonce. function getOperatorRegisterAgentsNonce(address operator, uint256 serviceId) external view returns (uint256 nonce) { // operator occupies first 160 bits uint256 operatorService = uint256(uint160(operator)); // serviceId occupies next 32 bits as serviceId is limited by the 2^32 - 1 value operatorService |= serviceId << 160; nonce = mapOperatorRegisterAgentsNonces[operatorService]; } }
{ "optimizer": { "enabled": true, "runs": 750 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_serviceRegistry","type":"address"},{"internalType":"address","name":"_serviceRegistryTokenUtility","type":"address"},{"internalType":"address","name":"_operatorWhitelist","type":"address"}],"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":"address","name":"operator","type":"address"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"HashNotApproved","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"HashNotValidated","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":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"provided","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"IncorrectSignatureLength","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":"address","name":"provided","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"WrongOperatorAddress","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":"ZeroOperatorAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"multisig","type":"address"}],"name":"CreateMultisig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"OperatorHashApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operatorWhitelist","type":"address"}],"name":"OperatorWhitelistUpdated","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":"owner","type":"address"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"Unpause","type":"event"},{"inputs":[],"name":"BOND_WRAPPER","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTER_AGENTS_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNBOND_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"activateRegistration","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"address","name":"token","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 IService.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":"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":"domainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getOperatorRegisterAgentsNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getOperatorUnbondNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"address[]","name":"agentInstances","type":"address[]"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"getRegisterAgentsHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"getUnbondHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"isOperatorHashApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"mapOperatorApprovedHashes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapOperatorRegisterAgentsNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapOperatorUnbondNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nameHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"operatorApproveHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operatorWhitelist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"address[]","name":"agentInstances","type":"address[]"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"registerAgentsWithSignature","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"serviceRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"serviceRegistryTokenUtility","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOperatorWhitelist","type":"address"}],"name":"setOperatorWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"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":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"unbondWithSignature","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"refund","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","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 IService.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"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"versionHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101406040523480156200001257600080fd5b506040516200365e3803806200365e8339810160408190526200003591620001cf565b6040518060400160405280601581526020017f53657276696365204d616e6167657220546f6b656e000000000000000000000081525060405180604001604052806005815260200164312e312e3160d81b81525081600190816200009a9190620002be565b506002620000a98282620002be565b50815160208084019190912060c05281519082012060e0524660a0526200013160c0805160e051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201526000910160405160208183030381529060405280519060200120905090565b60805250506001600160a01b03831615806200015457506001600160a01b038216155b15620001735760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03928316610100529082166101205260068054919092166001600160a01b03199182161790915560008054909116331790556200038a565b80516001600160a01b0381168114620001ca57600080fd5b919050565b600080600060608486031215620001e557600080fd5b620001f084620001b2565b92506200020060208501620001b2565b91506200021060408501620001b2565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200024457607f821691505b6020821081036200026557634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002b957600081815260208120601f850160051c81016020861015620002945750805b601f850160051c820191505b81811015620002b557828155600101620002a0565b5050505b505050565b81516001600160401b03811115620002da57620002da62000219565b620002f281620002eb84546200022f565b846200026b565b602080601f8311600181146200032a5760008415620003115750858301515b600019600386901b1c1916600185901b178555620002b5565b600085815260208120601f198616915b828110156200035b578886015182559484019460019091019084016200033a565b50858210156200037a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516131b9620004a56000396000818161042001528181610bc301528181610dcb01528181611030015281816111ec01528181611532015281816119a101528181611c0701528181611d420152612201015260008181610749015281816109c401528181610aa301528181610c4701528181610d0f01528181610e5701528181610ee8015281816110c80152818161127d01528181611318015281816115e00152818161190601528181611b6b01528181611dc801528181611e9001528181611faa015261216701526000818161033c01526122ea01526000818161083901526122c2015260008181610699015261226e0152600081816108a1015261234301526131b96000f3fe6080604052600436106102a05760003560e01c8063757b11561161016e578063cbcf252a116100cb578063e5da07531161007f578063f172a4ce11610064578063f172a4ce14610827578063f5dcb7bb1461085b578063f698da251461088f57600080fd5b8063e5da0753146107f2578063ed24911d1461081257600080fd5b8063d03ca40a116100b0578063d03ca40a1461078b578063dc1d95251461079e578063e42cdd7c146107d257600080fd5b8063cbcf252a14610737578063cbf994f81461076b57600080fd5b80639488791111610122578063a2e2ad7e11610107578063a2e2ad7e146106bb578063a6a7187f146106f7578063a6f9dae11461071757600080fd5b806394887911146106535780639a8a05921461068757600080fd5b80638456cb59116101535780638456cb59146105f15780638a39fa16146106065780638da5cb5b1461063357600080fd5b8063757b1156146105b15780637a828b28146105d157600080fd5b806328f223421161021c5780635405ecb9116101d057806356bda507116101b557806356bda50714610543578063599be46f146105705780635c975abb1461059057600080fd5b80635405ecb9146104f257806354fd4d501461052e57600080fd5b80633f4ba83a116102015780633f4ba83a1461049d57806341b60677146104b25780634d5a5827146104df57600080fd5b806328f22342146104425780633af5d04e1461046257600080fd5b80631878d1f11161027357806321561bfc1161025857806321561bfc146103b757806327de9e32146103d7578063287140511461040e57600080fd5b80631878d1f11461036c5780631ee81fb51461039457600080fd5b806306fdde03146102a557806307a3e0a8146102d05780630d0d57a8146102f2578063152b5c0f1461032a575b600080fd5b3480156102b157600080fd5b506102ba6108c3565b6040516102c79190612620565b60405180910390f35b3480156102dc57600080fd5b506102f06102eb36600461263a565b610951565b005b3480156102fe57600080fd5b5061031261030d36600461274b565b6109aa565b6040516001600160a01b0390911681526020016102c7565b34801561033657600080fd5b5061035e7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016102c7565b34801561037857600080fd5b5061031273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6103a76103a23660046128ac565b610a80565b60405190151581526020016102c7565b3480156103c357600080fd5b50600654610312906001600160a01b031681565b3480156103e357600080fd5b506103f76103f236600461263a565b610da0565b6040805192151583526020830191909152016102c7565b34801561041a57600080fd5b506103127f000000000000000000000000000000000000000000000000000000000000000081565b34801561044e57600080fd5b506103f761045d366004612951565b610ee1565b34801561046e57600080fd5b506103a761047d366004612994565b600560209081526000928352604080842090915290825290205460ff1681565b3480156104a957600080fd5b506102f0611152565b3480156104be57600080fd5b5061035e6104cd36600461263a565b60046020526000908152604090205481565b6103a76104ed36600461263a565b6111c9565b3480156104fe57600080fd5b5061035e61050d366004612994565b60a01b6001600160a01b039091161760009081526003602052604090205490565b34801561053a57600080fd5b506102ba611398565b34801561054f57600080fd5b50610558600181565b6040516001600160601b0390911681526020016102c7565b34801561057c57600080fd5b506102f061058b3660046129c0565b6113a5565b34801561059c57600080fd5b506000546103a790600160a01b900460ff1681565b3480156105bd57600080fd5b5061035e6105cc3660046129dd565b61143c565b3480156105dd57600080fd5b506103f76105ec36600461263a565b61152b565b3480156105fd57600080fd5b506102f0611617565b34801561061257600080fd5b5061035e61062136600461263a565b60036020526000908152604090205481565b34801561063f57600080fd5b50600054610312906001600160a01b031681565b34801561065f57600080fd5b5061035e7f92b2008d2a99f26809ac9d1989fe92334aa84124767331997ba0eec16050ecf481565b34801561069357600080fd5b5061035e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106c757600080fd5b5061035e6106d6366004612994565b60a01b6001600160a01b039091161760009081526004602052604090205490565b34801561070357600080fd5b5061035e610712366004612a78565b611694565b34801561072357600080fd5b506102f06107323660046129c0565b611750565b34801561074357600080fd5b506103127f000000000000000000000000000000000000000000000000000000000000000081565b34801561077757600080fd5b506103a7610786366004612b5a565b61180c565b6103a7610799366004612bf3565b611c81565b3480156107aa57600080fd5b5061035e7fde64b4c9fac43e1615e938b03573b078604f57b4d2e78d3a27d7b20ba017e12681565b3480156107de57600080fd5b5061035e6107ed366004612c56565b611f1b565b3480156107fe57600080fd5b506103a761080d366004612994565b61223c565b34801561081e57600080fd5b5061035e61226a565b34801561083357600080fd5b5061035e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561086757600080fd5b5061035e7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b34801561089b57600080fd5b5061035e7f000000000000000000000000000000000000000000000000000000000000000081565b600180546108d090612cf8565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90612cf8565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b505050505081565b336000818152600560209081526040808320858452825291829020805460ff1916600117905590518381527f85eb1f050732417c0566422b6004a6c5cbded9ded1a406de04060719af52a13a910160405180910390a250565b60405163f908bc7760e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f908bc77906109ff903390889088908890600401612d2c565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a429190612d5e565b6040519091506001600160a01b038216907fec97633905b1dbe9773a7536e9a986dcf89803e1193934b7b6d76587c68beb4090600090a29392505050565b6040516331a9108f60e11b81526004810185905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e9190612d5e565b9050336001600160a01b03821614610b4f5760405163521eb56d60e11b81523360048201526001600160a01b03821660248201526044015b60405180910390fd5b60a086901b6001600160a01b0388161760008181526004602052604081205490610b7d8a858b8b8b8761143c565b9050610b8a8a8288612365565b81610b9481612d91565b60008581526004602081905260408083208490555163dc4f8bc560e01b81529295509092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163dc4f8bc591610bfa918f918f918e9101612deb565b6020604051808303816000875af1158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3d9190612e2c565b90508015610cf8577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663dff7672460016001600160601b03168b51610c8b9190612e47565b8d8d8d8d6040518663ffffffff1660e01b8152600401610cae9493929190612e97565b60206040518083038185885af1158015610ccc573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610cf19190612e2c565b9550610d92565b6040516337fdd9c960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dff76724903490610d4c908f908f908f908f90600401612e97565b60206040518083038185885af1158015610d6a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610d8f9190612e2c565b95505b505050505095945050505050565b60405163161e984960e31b815233600482015260248101829052600090819081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b0f4c248906044016020604051808303816000875af1158015610e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e389190612edc565b6040516352e82ce560e11b8152336004820152602481018690529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5d059ca906044015b60408051808303816000875af1158015610ea8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecc9190612ef5565b90935091508015610edb578091505b50915091565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e866040518263ffffffff1660e01b8152600401610f3491815260200190565b602060405180830381865afa158015610f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f759190612d5e565b9050336001600160a01b03821614610fb15760405163521eb56d60e11b81523360048201526001600160a01b0382166024820152604401610b46565b60a085901b6001600160a01b0387161760008181526003602052604081205490610fdd89858a85611694565b9050610fea898289612365565b81610ff481612d91565b6000858152600360205260408082208390555163161e984960e31b81526001600160a01b038d81166004830152602482018d90529295509092507f00000000000000000000000000000000000000000000000000000000000000009091169063b0f4c248906044016020604051808303816000875af115801561107b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109f9190612edc565b6040516352e82ce560e11b81526001600160a01b038c81166004830152602482018c90529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a5d059ca9060440160408051808303816000875af1158015611112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111369190612ef5565b90975095508015611145578095505b5050505050935093915050565b6000546001600160a01b031633146111925760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6000805460ff60a01b1916815560405133917faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf491a2565b60405163542db44960e01b81526004810182905260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063542db449906024016020604051808303816000875af1158015611235573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112599190612e2c565b905080156112fc5760405163388fdbed60e21b8152336004820152602481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e23f6fb49060019060440160206040518083038185885af11580156112d0573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112f59190612e2c565b9150611392565b60405163388fdbed60e21b8152336004820152602481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e23f6fb490349060440160206040518083038185885af115801561136a573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061138f9190612e2c565b91505b50919050565b600280546108d090612cf8565b6000546001600160a01b031633146113e55760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517ff8e76e8a7c35558598a944d509f1ed32b104e77b1098ef1dfa5b97b86b09df8f90600090a250565b600061144661226a565b7fde64b4c9fac43e1615e938b03573b078604f57b4d2e78d3a27d7b20ba017e126888888888860405160200161147d929190612f21565b60408051601f198184030181528282528051602091820120908301969096526001600160a01b0394851690820152929091166060830152608082015260a081019190915260c0810184905260e0016040516020818303038152906040528051906020012060405160200161150892919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090505b9695505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166325e1afc3856040518263ffffffff1660e01b815260040161157e91815260200190565b6020604051808303816000875af115801561159d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c19190612edc565b60405163ccc9305d60e01b8152336004820152602481018690529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ccc9305d90604401610e8a565b6000546001600160a01b031633146116575760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6000805460ff60a01b1916600160a01b17815560405133917f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca39991a2565b600061169e61226a565b604080517f92b2008d2a99f26809ac9d1989fe92334aa84124767331997ba0eec16050ecf460208201526001600160a01b038089169282019290925290861660608201526080810185905260a0810184905260c0016040516020818303038152906040528051906020012060405160200161173092919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050949350505050565b6000546001600160a01b031633146117905760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6001600160a01b0381166117b75760405163d92e233d60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b60006001600160a01b0387166118355760405163d92e233d60e01b815260040160405180910390fd5b835173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03891601611a0a5760005b818110156118ee57600086828151811061187b5761187b612f46565b60200260200101516000015163ffffffff161180156118c057508581815181106118a7576118a7612f46565b6020026020010151602001516001600160601b03166000145b156118de57604051637c946ed760e01b815260040160405180910390fd5b6118e781612d91565b905061185f565b5060405163197f329f60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbf994f8906119459033908b908b908b908b908b90600401612fa6565b6020604051808303816000875af1158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e2c565b604051630be6cc4b60e31b8152600481018590529092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635f36625890602401600060405180830381600087803b1580156119ed57600080fd5b505af1158015611a01573d6000803e3d6000fd5b50505050611c76565b60008167ffffffffffffffff811115611a2557611a2561266b565b604051908082528060200260200182016040528015611a4e578160200160208202803683370190505b50905060005b82811015611b53576000878281518110611a7057611a70612f46565b60200260200101516000015163ffffffff161115611b4357868181518110611a9a57611a9a612f46565b6020026020010151602001516001600160601b0316600003611acf57604051637c946ed760e01b815260040160405180910390fd5b868181518110611ae157611ae1612f46565b6020026020010151602001516001600160601b0316828281518110611b0857611b08612f46565b6020026020010181815250506001878281518110611b2857611b28612f46565b6020908102919091018101516001600160601b039092169101525b611b4c81612d91565b9050611a54565b5060405163197f329f60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbf994f890611baa9033908c908c908c908c908c90600401612fa6565b6020604051808303816000875af1158015611bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bed9190612e2c565b6040516338f3a6a160e21b81529093506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e3ce9a8490611c429087908d908c908790600401612ffc565b600060405180830381600087803b158015611c5c57600080fd5b505af1158015611c70573d6000803e3d6000fd5b50505050505b509695505050505050565b6006546000906001600160a01b031615611d28576006546040516356a7b60760e01b8152600481018690523360248201526001600160a01b03909116906356a7b60790604401602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d089190612e2c565b611d28576040516322ddebd960e21b815260048101859052602401610b46565b60405163dc4f8bc560e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc4f8bc590611d7b90339089908890600401612deb565b6020604051808303816000875af1158015611d9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dbe9190612e2c565b90508015611e79577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663dff7672460016001600160601b03168651611e0c9190612e47565b338888886040518663ffffffff1660e01b8152600401611e2f9493929190612e97565b60206040518083038185885af1158015611e4d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e729190612e2c565b9150611f13565b6040516337fdd9c960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dff76724903490611ecd9033908a908a908a90600401612e97565b60206040518083038185885af1158015611eeb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f109190612e2c565b91505b509392505050565b60008054600160a01b900460ff1615611f47576040516313d0ff5960e31b815260040160405180910390fd5b6001600160a01b038616611f6e5760405163d92e233d60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016120315760405163fbdeb3d760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063fbdeb3d790611fe7908a908990899089908990600401613067565b6020604051808303816000875af1158015612006573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202a9190612edc565b9050611521565b825160008167ffffffffffffffff81111561204e5761204e61266b565b604051908082528060200260200182016040528015612077578160200160208202803683370190505b50905060005b8281101561214f5785818151811061209757612097612f46565b6020026020010151602001516001600160601b03166000036120cc57604051637c946ed760e01b815260040160405180910390fd5b8581815181106120de576120de612f46565b6020026020010151602001516001600160601b031682828151811061210557612105612f46565b602002602001018181525050600186828151811061212557612125612f46565b6020908102919091018101516001600160601b0390921691015261214881612d91565b905061207d565b5060405163fbdeb3d760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063fbdeb3d7906121a4908c908b908b908b908b90600401613067565b6020604051808303816000875af11580156121c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e79190612edc565b6040516338f3a6a160e21b81529093506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e3ce9a8490611c429086908c908b908790600401612ffc565b6001600160a01b038216600090815260056020908152604080832084845290915290205460ff165b92915050565b60007f000000000000000000000000000000000000000000000000000000000000000046146123405761233b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6001600160a01b03831661238c5760405163e63f571f60e01b815260040160405180910390fd5b80516041146123b5578051604051631d9f5a5f60e01b8152610b469183916041906004016130ba565b6000816040815181106123ca576123ca612f46565b016020015160f81c90506004811080156123ec57506001600160a01b0384163b155b156123ff576123fc601b826130df565b90505b60208201516040830151600060ff84166004036124d45750604051630b135d3f60e11b80825283916001600160a01b03831690631626ba7e90612448908a908a906004016130f8565b602060405180830381865afa158015612465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124899190613119565b7fffffffff0000000000000000000000000000000000000000000000000000000016146124cf5780868660405163694d54dd60e01b8152600401610b469392919061315b565b61258c565b8360ff1660050361252c57506001600160a01b0382166000908152600560209081526040808320888452909152902054829060ff166124cf578086866040516312cf832560e01b8152600401610b469392919061315b565b60408051600081526020810180835288905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561257f573d6000803e3d6000fd5b5050506020604051035190505b866001600160a01b0316816001600160a01b0316146125d15760405163a806216d60e01b81526001600160a01b03808316600483015288166024820152604401610b46565b50505050505050565b6000815180845260005b81811015612600576020818501810151868301820152016125e4565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061263360208301846125da565b9392505050565b60006020828403121561264c57600080fd5b5035919050565b6001600160a01b038116811461266857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156126a4576126a461266b565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156126d3576126d361266b565b604052919050565b600082601f8301126126ec57600080fd5b813567ffffffffffffffff8111156127065761270661266b565b612719601f8201601f19166020016126aa565b81815284602083860101111561272e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561276057600080fd5b83359250602084013561277281612653565b9150604084013567ffffffffffffffff81111561278e57600080fd5b61279a868287016126db565b9150509250925092565b600067ffffffffffffffff8211156127be576127be61266b565b5060051b60200190565b600082601f8301126127d957600080fd5b813560206127ee6127e9836127a4565b6126aa565b82815260059290921b8401810191818101908684111561280d57600080fd5b8286015b84811015611c7657803561282481612653565b8352918301918301612811565b803563ffffffff8116811461284557600080fd5b919050565b600082601f83011261285b57600080fd5b8135602061286b6127e9836127a4565b82815260059290921b8401810191818101908684111561288a57600080fd5b8286015b84811015611c765761289f81612831565b835291830191830161288e565b600080600080600060a086880312156128c457600080fd5b85356128cf81612653565b945060208601359350604086013567ffffffffffffffff808211156128f357600080fd5b6128ff89838a016127c8565b9450606088013591508082111561291557600080fd5b61292189838a0161284a565b9350608088013591508082111561293757600080fd5b50612944888289016126db565b9150509295509295909350565b60008060006060848603121561296657600080fd5b833561297181612653565b925060208401359150604084013567ffffffffffffffff81111561278e57600080fd5b600080604083850312156129a757600080fd5b82356129b281612653565b946020939093013593505050565b6000602082840312156129d257600080fd5b813561263381612653565b60008060008060008060c087890312156129f657600080fd5b8635612a0181612653565b95506020870135612a1181612653565b945060408701359350606087013567ffffffffffffffff80821115612a3557600080fd5b612a418a838b016127c8565b94506080890135915080821115612a5757600080fd5b50612a6489828a0161284a565b92505060a087013590509295509295509295565b60008060008060808587031215612a8e57600080fd5b8435612a9981612653565b93506020850135612aa981612653565b93969395505050506040820135916060013590565b600082601f830112612acf57600080fd5b81356020612adf6127e9836127a4565b82815260069290921b84018101918181019086841115612afe57600080fd5b8286015b84811015611c765760408189031215612b1b5760008081fd5b612b23612681565b612b2c82612831565b8152848201356001600160601b0381168114612b485760008081fd5b81860152835291830191604001612b02565b60008060008060008060c08789031215612b7357600080fd5b8635612b7e81612653565b955060208701359450604087013567ffffffffffffffff80821115612ba257600080fd5b612bae8a838b0161284a565b95506060890135915080821115612bc457600080fd5b50612bd189828a01612abe565b935050612be060808801612831565b915060a087013590509295509295509295565b600080600060608486031215612c0857600080fd5b83359250602084013567ffffffffffffffff80821115612c2757600080fd5b612c33878388016127c8565b93506040860135915080821115612c4957600080fd5b5061279a8682870161284a565b60008060008060008060c08789031215612c6f57600080fd5b8635612c7a81612653565b95506020870135612c8a81612653565b945060408701359350606087013567ffffffffffffffff80821115612cae57600080fd5b612cba8a838b0161284a565b94506080890135915080821115612cd057600080fd5b50612cdd89828a01612abe565b925050612cec60a08801612831565b90509295509295509295565b600181811c90821680612d0c57607f821691505b60208210810361139257634e487b7160e01b600052602260045260246000fd5b60006001600160a01b0380871683528560208401528085166040840152506080606083015261152160808301846125da565b600060208284031215612d7057600080fd5b815161263381612653565b634e487b7160e01b600052601160045260246000fd5b600060018201612da357612da3612d7b565b5060010190565b600081518084526020808501945080840160005b83811015612de057815163ffffffff1687529582019590820190600101612dbe565b509495945050505050565b6001600160a01b0384168152826020820152606060408201526000612e136060830184612daa565b95945050505050565b8051801515811461284557600080fd5b600060208284031215612e3e57600080fd5b61263382612e1c565b808202811582820484141761226457612264612d7b565b600081518084526020808501945080840160005b83811015612de05781516001600160a01b031687529582019590820190600101612e72565b6001600160a01b0385168152836020820152608060408201526000612ebf6080830185612e5e565b8281036060840152612ed18185612daa565b979650505050505050565b600060208284031215612eee57600080fd5b5051919050565b60008060408385031215612f0857600080fd5b612f1183612e1c565b9150602083015190509250929050565b604081526000612f346040830185612e5e565b8281036020840152611f108185612daa565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015612de0578151805163ffffffff1688528301516001600160601b03168388015260409096019590820190600101612f70565b6001600160a01b038716815285602082015260c060408201526000612fce60c0830187612daa565b8281036060840152612fe08187612f5c565b63ffffffff959095166080840152505060a00152949350505050565b848152600060206001600160a01b03861681840152608060408401526130256080840186612daa565b838103606085015284518082528286019183019060005b818110156130585783518352928401929184019160010161303c565b50909998505050505050505050565b6001600160a01b038616815284602082015260a06040820152600061308f60a0830186612daa565b82810360608401526130a18186612f5c565b91505063ffffffff831660808301529695505050505050565b6060815260006130cd60608301866125da565b60208301949094525060400152919050565b60ff818116838216019081111561226457612264612d7b565b82815260406020820152600061311160408301846125da565b949350505050565b60006020828403121561312b57600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461263357600080fd5b6001600160a01b0384168152826020820152606060408201526000612e1360608301846125da56fea2646970667358221220f2d50ac7cf109448ada9fff306a728e5251fe66a1c6e6ec31ba9ad713c2ad83964736f6c6343000813003300000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa00000000000000000000000042042799b0de38add2a70dc996f69f98e1a85260
Deployed Bytecode
0x6080604052600436106102a05760003560e01c8063757b11561161016e578063cbcf252a116100cb578063e5da07531161007f578063f172a4ce11610064578063f172a4ce14610827578063f5dcb7bb1461085b578063f698da251461088f57600080fd5b8063e5da0753146107f2578063ed24911d1461081257600080fd5b8063d03ca40a116100b0578063d03ca40a1461078b578063dc1d95251461079e578063e42cdd7c146107d257600080fd5b8063cbcf252a14610737578063cbf994f81461076b57600080fd5b80639488791111610122578063a2e2ad7e11610107578063a2e2ad7e146106bb578063a6a7187f146106f7578063a6f9dae11461071757600080fd5b806394887911146106535780639a8a05921461068757600080fd5b80638456cb59116101535780638456cb59146105f15780638a39fa16146106065780638da5cb5b1461063357600080fd5b8063757b1156146105b15780637a828b28146105d157600080fd5b806328f223421161021c5780635405ecb9116101d057806356bda507116101b557806356bda50714610543578063599be46f146105705780635c975abb1461059057600080fd5b80635405ecb9146104f257806354fd4d501461052e57600080fd5b80633f4ba83a116102015780633f4ba83a1461049d57806341b60677146104b25780634d5a5827146104df57600080fd5b806328f22342146104425780633af5d04e1461046257600080fd5b80631878d1f11161027357806321561bfc1161025857806321561bfc146103b757806327de9e32146103d7578063287140511461040e57600080fd5b80631878d1f11461036c5780631ee81fb51461039457600080fd5b806306fdde03146102a557806307a3e0a8146102d05780630d0d57a8146102f2578063152b5c0f1461032a575b600080fd5b3480156102b157600080fd5b506102ba6108c3565b6040516102c79190612620565b60405180910390f35b3480156102dc57600080fd5b506102f06102eb36600461263a565b610951565b005b3480156102fe57600080fd5b5061031261030d36600461274b565b6109aa565b6040516001600160a01b0390911681526020016102c7565b34801561033657600080fd5b5061035e7f9dd6d964e72a376a8989d1d2720ab48ff4f2ad77466fb517dabc84f4a79478d481565b6040519081526020016102c7565b34801561037857600080fd5b5061031273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6103a76103a23660046128ac565b610a80565b60405190151581526020016102c7565b3480156103c357600080fd5b50600654610312906001600160a01b031681565b3480156103e357600080fd5b506103f76103f236600461263a565b610da0565b6040805192151583526020830191909152016102c7565b34801561041a57600080fd5b506103127f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa81565b34801561044e57600080fd5b506103f761045d366004612951565b610ee1565b34801561046e57600080fd5b506103a761047d366004612994565b600560209081526000928352604080842090915290825290205460ff1681565b3480156104a957600080fd5b506102f0611152565b3480156104be57600080fd5b5061035e6104cd36600461263a565b60046020526000908152604090205481565b6103a76104ed36600461263a565b6111c9565b3480156104fe57600080fd5b5061035e61050d366004612994565b60a01b6001600160a01b039091161760009081526003602052604090205490565b34801561053a57600080fd5b506102ba611398565b34801561054f57600080fd5b50610558600181565b6040516001600160601b0390911681526020016102c7565b34801561057c57600080fd5b506102f061058b3660046129c0565b6113a5565b34801561059c57600080fd5b506000546103a790600160a01b900460ff1681565b3480156105bd57600080fd5b5061035e6105cc3660046129dd565b61143c565b3480156105dd57600080fd5b506103f76105ec36600461263a565b61152b565b3480156105fd57600080fd5b506102f0611617565b34801561061257600080fd5b5061035e61062136600461263a565b60036020526000908152604090205481565b34801561063f57600080fd5b50600054610312906001600160a01b031681565b34801561065f57600080fd5b5061035e7f92b2008d2a99f26809ac9d1989fe92334aa84124767331997ba0eec16050ecf481565b34801561069357600080fd5b5061035e7f000000000000000000000000000000000000000000000000000000000000000181565b3480156106c757600080fd5b5061035e6106d6366004612994565b60a01b6001600160a01b039091161760009081526004602052604090205490565b34801561070357600080fd5b5061035e610712366004612a78565b611694565b34801561072357600080fd5b506102f06107323660046129c0565b611750565b34801561074357600080fd5b506103127f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca81565b34801561077757600080fd5b506103a7610786366004612b5a565b61180c565b6103a7610799366004612bf3565b611c81565b3480156107aa57600080fd5b5061035e7fde64b4c9fac43e1615e938b03573b078604f57b4d2e78d3a27d7b20ba017e12681565b3480156107de57600080fd5b5061035e6107ed366004612c56565b611f1b565b3480156107fe57600080fd5b506103a761080d366004612994565b61223c565b34801561081e57600080fd5b5061035e61226a565b34801561083357600080fd5b5061035e7fe7800624217e1c766f5717ba8792e0b2f3e1c1bda11f870b724d9bef903d5b2d81565b34801561086757600080fd5b5061035e7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b34801561089b57600080fd5b5061035e7f27b1db74c9a3fc9e566972b761e2366b72470c34498303516dad89ec572a88e781565b600180546108d090612cf8565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90612cf8565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b505050505081565b336000818152600560209081526040808320858452825291829020805460ff1916600117905590518381527f85eb1f050732417c0566422b6004a6c5cbded9ded1a406de04060719af52a13a910160405180910390a250565b60405163f908bc7760e01b81526000906001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063f908bc77906109ff903390889088908890600401612d2c565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a429190612d5e565b6040519091506001600160a01b038216907fec97633905b1dbe9773a7536e9a986dcf89803e1193934b7b6d76587c68beb4090600090a29392505050565b6040516331a9108f60e11b81526004810185905260009081906001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca1690636352211e90602401602060405180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e9190612d5e565b9050336001600160a01b03821614610b4f5760405163521eb56d60e11b81523360048201526001600160a01b03821660248201526044015b60405180910390fd5b60a086901b6001600160a01b0388161760008181526004602052604081205490610b7d8a858b8b8b8761143c565b9050610b8a8a8288612365565b81610b9481612d91565b60008581526004602081905260408083208490555163dc4f8bc560e01b81529295509092506001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169163dc4f8bc591610bfa918f918f918e9101612deb565b6020604051808303816000875af1158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3d9190612e2c565b90508015610cf8577f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b031663dff7672460016001600160601b03168b51610c8b9190612e47565b8d8d8d8d6040518663ffffffff1660e01b8152600401610cae9493929190612e97565b60206040518083038185885af1158015610ccc573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610cf19190612e2c565b9550610d92565b6040516337fdd9c960e21b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063dff76724903490610d4c908f908f908f908f90600401612e97565b60206040518083038185885af1158015610d6a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610d8f9190612e2c565b95505b505050505095945050505050565b60405163161e984960e31b815233600482015260248101829052600090819081906001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169063b0f4c248906044016020604051808303816000875af1158015610e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e389190612edc565b6040516352e82ce560e11b8152336004820152602481018690529091507f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b03169063a5d059ca906044015b60408051808303816000875af1158015610ea8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecc9190612ef5565b90935091508015610edb578091505b50915091565b60008060007f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b0316636352211e866040518263ffffffff1660e01b8152600401610f3491815260200190565b602060405180830381865afa158015610f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f759190612d5e565b9050336001600160a01b03821614610fb15760405163521eb56d60e11b81523360048201526001600160a01b0382166024820152604401610b46565b60a085901b6001600160a01b0387161760008181526003602052604081205490610fdd89858a85611694565b9050610fea898289612365565b81610ff481612d91565b6000858152600360205260408082208390555163161e984960e31b81526001600160a01b038d81166004830152602482018d90529295509092507f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa9091169063b0f4c248906044016020604051808303816000875af115801561107b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109f9190612edc565b6040516352e82ce560e11b81526001600160a01b038c81166004830152602482018c90529192507f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca9091169063a5d059ca9060440160408051808303816000875af1158015611112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111369190612ef5565b90975095508015611145578095505b5050505050935093915050565b6000546001600160a01b031633146111925760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6000805460ff60a01b1916815560405133917faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf491a2565b60405163542db44960e01b81526004810182905260009081906001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169063542db449906024016020604051808303816000875af1158015611235573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112599190612e2c565b905080156112fc5760405163388fdbed60e21b8152336004820152602481018490527f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b03169063e23f6fb49060019060440160206040518083038185885af11580156112d0573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112f59190612e2c565b9150611392565b60405163388fdbed60e21b8152336004820152602481018490527f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b03169063e23f6fb490349060440160206040518083038185885af115801561136a573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061138f9190612e2c565b91505b50919050565b600280546108d090612cf8565b6000546001600160a01b031633146113e55760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517ff8e76e8a7c35558598a944d509f1ed32b104e77b1098ef1dfa5b97b86b09df8f90600090a250565b600061144661226a565b7fde64b4c9fac43e1615e938b03573b078604f57b4d2e78d3a27d7b20ba017e126888888888860405160200161147d929190612f21565b60408051601f198184030181528282528051602091820120908301969096526001600160a01b0394851690820152929091166060830152608082015260a081019190915260c0810184905260e0016040516020818303038152906040528051906020012060405160200161150892919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090505b9695505050505050565b60008060007f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa6001600160a01b03166325e1afc3856040518263ffffffff1660e01b815260040161157e91815260200190565b6020604051808303816000875af115801561159d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c19190612edc565b60405163ccc9305d60e01b8152336004820152602481018690529091507f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b03169063ccc9305d90604401610e8a565b6000546001600160a01b031633146116575760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6000805460ff60a01b1916600160a01b17815560405133917f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca39991a2565b600061169e61226a565b604080517f92b2008d2a99f26809ac9d1989fe92334aa84124767331997ba0eec16050ecf460208201526001600160a01b038089169282019290925290861660608201526080810185905260a0810184905260c0016040516020818303038152906040528051906020012060405160200161173092919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050949350505050565b6000546001600160a01b031633146117905760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610b46565b6001600160a01b0381166117b75760405163d92e233d60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b60006001600160a01b0387166118355760405163d92e233d60e01b815260040160405180910390fd5b835173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03891601611a0a5760005b818110156118ee57600086828151811061187b5761187b612f46565b60200260200101516000015163ffffffff161180156118c057508581815181106118a7576118a7612f46565b6020026020010151602001516001600160601b03166000145b156118de57604051637c946ed760e01b815260040160405180910390fd5b6118e781612d91565b905061185f565b5060405163197f329f60e31b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063cbf994f8906119459033908b908b908b908b908b90600401612fa6565b6020604051808303816000875af1158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e2c565b604051630be6cc4b60e31b8152600481018590529092507f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa6001600160a01b031690635f36625890602401600060405180830381600087803b1580156119ed57600080fd5b505af1158015611a01573d6000803e3d6000fd5b50505050611c76565b60008167ffffffffffffffff811115611a2557611a2561266b565b604051908082528060200260200182016040528015611a4e578160200160208202803683370190505b50905060005b82811015611b53576000878281518110611a7057611a70612f46565b60200260200101516000015163ffffffff161115611b4357868181518110611a9a57611a9a612f46565b6020026020010151602001516001600160601b0316600003611acf57604051637c946ed760e01b815260040160405180910390fd5b868181518110611ae157611ae1612f46565b6020026020010151602001516001600160601b0316828281518110611b0857611b08612f46565b6020026020010181815250506001878281518110611b2857611b28612f46565b6020908102919091018101516001600160601b039092169101525b611b4c81612d91565b9050611a54565b5060405163197f329f60e31b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063cbf994f890611baa9033908c908c908c908c908c90600401612fa6565b6020604051808303816000875af1158015611bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bed9190612e2c565b6040516338f3a6a160e21b81529093506001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169063e3ce9a8490611c429087908d908c908790600401612ffc565b600060405180830381600087803b158015611c5c57600080fd5b505af1158015611c70573d6000803e3d6000fd5b50505050505b509695505050505050565b6006546000906001600160a01b031615611d28576006546040516356a7b60760e01b8152600481018690523360248201526001600160a01b03909116906356a7b60790604401602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d089190612e2c565b611d28576040516322ddebd960e21b815260048101859052602401610b46565b60405163dc4f8bc560e01b81526000906001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169063dc4f8bc590611d7b90339089908890600401612deb565b6020604051808303816000875af1158015611d9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dbe9190612e2c565b90508015611e79577f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca6001600160a01b031663dff7672460016001600160601b03168651611e0c9190612e47565b338888886040518663ffffffff1660e01b8152600401611e2f9493929190612e97565b60206040518083038185885af1158015611e4d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e729190612e2c565b9150611f13565b6040516337fdd9c960e21b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063dff76724903490611ecd9033908a908a908a90600401612e97565b60206040518083038185885af1158015611eeb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f109190612e2c565b91505b509392505050565b60008054600160a01b900460ff1615611f47576040516313d0ff5960e31b815260040160405180910390fd5b6001600160a01b038616611f6e5760405163d92e233d60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016120315760405163fbdeb3d760e01b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063fbdeb3d790611fe7908a908990899089908990600401613067565b6020604051808303816000875af1158015612006573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202a9190612edc565b9050611521565b825160008167ffffffffffffffff81111561204e5761204e61266b565b604051908082528060200260200182016040528015612077578160200160208202803683370190505b50905060005b8281101561214f5785818151811061209757612097612f46565b6020026020010151602001516001600160601b03166000036120cc57604051637c946ed760e01b815260040160405180910390fd5b8581815181106120de576120de612f46565b6020026020010151602001516001600160601b031682828151811061210557612105612f46565b602002602001018181525050600186828151811061212557612125612f46565b6020908102919091018101516001600160601b0390921691015261214881612d91565b905061207d565b5060405163fbdeb3d760e01b81526001600160a01b037f00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca169063fbdeb3d7906121a4908c908b908b908b908b90600401613067565b6020604051808303816000875af11580156121c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e79190612edc565b6040516338f3a6a160e21b81529093506001600160a01b037f0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa169063e3ce9a8490611c429086908c908b908790600401612ffc565b6001600160a01b038216600090815260056020908152604080832084845290915290205460ff165b92915050565b60007f000000000000000000000000000000000000000000000000000000000000000146146123405761233b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527fe7800624217e1c766f5717ba8792e0b2f3e1c1bda11f870b724d9bef903d5b2d918101919091527f9dd6d964e72a376a8989d1d2720ab48ff4f2ad77466fb517dabc84f4a79478d460608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b507f27b1db74c9a3fc9e566972b761e2366b72470c34498303516dad89ec572a88e790565b6001600160a01b03831661238c5760405163e63f571f60e01b815260040160405180910390fd5b80516041146123b5578051604051631d9f5a5f60e01b8152610b469183916041906004016130ba565b6000816040815181106123ca576123ca612f46565b016020015160f81c90506004811080156123ec57506001600160a01b0384163b155b156123ff576123fc601b826130df565b90505b60208201516040830151600060ff84166004036124d45750604051630b135d3f60e11b80825283916001600160a01b03831690631626ba7e90612448908a908a906004016130f8565b602060405180830381865afa158015612465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124899190613119565b7fffffffff0000000000000000000000000000000000000000000000000000000016146124cf5780868660405163694d54dd60e01b8152600401610b469392919061315b565b61258c565b8360ff1660050361252c57506001600160a01b0382166000908152600560209081526040808320888452909152902054829060ff166124cf578086866040516312cf832560e01b8152600401610b469392919061315b565b60408051600081526020810180835288905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561257f573d6000803e3d6000fd5b5050506020604051035190505b866001600160a01b0316816001600160a01b0316146125d15760405163a806216d60e01b81526001600160a01b03808316600483015288166024820152604401610b46565b50505050505050565b6000815180845260005b81811015612600576020818501810151868301820152016125e4565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061263360208301846125da565b9392505050565b60006020828403121561264c57600080fd5b5035919050565b6001600160a01b038116811461266857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156126a4576126a461266b565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156126d3576126d361266b565b604052919050565b600082601f8301126126ec57600080fd5b813567ffffffffffffffff8111156127065761270661266b565b612719601f8201601f19166020016126aa565b81815284602083860101111561272e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561276057600080fd5b83359250602084013561277281612653565b9150604084013567ffffffffffffffff81111561278e57600080fd5b61279a868287016126db565b9150509250925092565b600067ffffffffffffffff8211156127be576127be61266b565b5060051b60200190565b600082601f8301126127d957600080fd5b813560206127ee6127e9836127a4565b6126aa565b82815260059290921b8401810191818101908684111561280d57600080fd5b8286015b84811015611c7657803561282481612653565b8352918301918301612811565b803563ffffffff8116811461284557600080fd5b919050565b600082601f83011261285b57600080fd5b8135602061286b6127e9836127a4565b82815260059290921b8401810191818101908684111561288a57600080fd5b8286015b84811015611c765761289f81612831565b835291830191830161288e565b600080600080600060a086880312156128c457600080fd5b85356128cf81612653565b945060208601359350604086013567ffffffffffffffff808211156128f357600080fd5b6128ff89838a016127c8565b9450606088013591508082111561291557600080fd5b61292189838a0161284a565b9350608088013591508082111561293757600080fd5b50612944888289016126db565b9150509295509295909350565b60008060006060848603121561296657600080fd5b833561297181612653565b925060208401359150604084013567ffffffffffffffff81111561278e57600080fd5b600080604083850312156129a757600080fd5b82356129b281612653565b946020939093013593505050565b6000602082840312156129d257600080fd5b813561263381612653565b60008060008060008060c087890312156129f657600080fd5b8635612a0181612653565b95506020870135612a1181612653565b945060408701359350606087013567ffffffffffffffff80821115612a3557600080fd5b612a418a838b016127c8565b94506080890135915080821115612a5757600080fd5b50612a6489828a0161284a565b92505060a087013590509295509295509295565b60008060008060808587031215612a8e57600080fd5b8435612a9981612653565b93506020850135612aa981612653565b93969395505050506040820135916060013590565b600082601f830112612acf57600080fd5b81356020612adf6127e9836127a4565b82815260069290921b84018101918181019086841115612afe57600080fd5b8286015b84811015611c765760408189031215612b1b5760008081fd5b612b23612681565b612b2c82612831565b8152848201356001600160601b0381168114612b485760008081fd5b81860152835291830191604001612b02565b60008060008060008060c08789031215612b7357600080fd5b8635612b7e81612653565b955060208701359450604087013567ffffffffffffffff80821115612ba257600080fd5b612bae8a838b0161284a565b95506060890135915080821115612bc457600080fd5b50612bd189828a01612abe565b935050612be060808801612831565b915060a087013590509295509295509295565b600080600060608486031215612c0857600080fd5b83359250602084013567ffffffffffffffff80821115612c2757600080fd5b612c33878388016127c8565b93506040860135915080821115612c4957600080fd5b5061279a8682870161284a565b60008060008060008060c08789031215612c6f57600080fd5b8635612c7a81612653565b95506020870135612c8a81612653565b945060408701359350606087013567ffffffffffffffff80821115612cae57600080fd5b612cba8a838b0161284a565b94506080890135915080821115612cd057600080fd5b50612cdd89828a01612abe565b925050612cec60a08801612831565b90509295509295509295565b600181811c90821680612d0c57607f821691505b60208210810361139257634e487b7160e01b600052602260045260246000fd5b60006001600160a01b0380871683528560208401528085166040840152506080606083015261152160808301846125da565b600060208284031215612d7057600080fd5b815161263381612653565b634e487b7160e01b600052601160045260246000fd5b600060018201612da357612da3612d7b565b5060010190565b600081518084526020808501945080840160005b83811015612de057815163ffffffff1687529582019590820190600101612dbe565b509495945050505050565b6001600160a01b0384168152826020820152606060408201526000612e136060830184612daa565b95945050505050565b8051801515811461284557600080fd5b600060208284031215612e3e57600080fd5b61263382612e1c565b808202811582820484141761226457612264612d7b565b600081518084526020808501945080840160005b83811015612de05781516001600160a01b031687529582019590820190600101612e72565b6001600160a01b0385168152836020820152608060408201526000612ebf6080830185612e5e565b8281036060840152612ed18185612daa565b979650505050505050565b600060208284031215612eee57600080fd5b5051919050565b60008060408385031215612f0857600080fd5b612f1183612e1c565b9150602083015190509250929050565b604081526000612f346040830185612e5e565b8281036020840152611f108185612daa565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015612de0578151805163ffffffff1688528301516001600160601b03168388015260409096019590820190600101612f70565b6001600160a01b038716815285602082015260c060408201526000612fce60c0830187612daa565b8281036060840152612fe08187612f5c565b63ffffffff959095166080840152505060a00152949350505050565b848152600060206001600160a01b03861681840152608060408401526130256080840186612daa565b838103606085015284518082528286019183019060005b818110156130585783518352928401929184019160010161303c565b50909998505050505050505050565b6001600160a01b038616815284602082015260a06040820152600061308f60a0830186612daa565b82810360608401526130a18186612f5c565b91505063ffffffff831660808301529695505050505050565b6060815260006130cd60608301866125da565b60208301949094525060400152919050565b60ff818116838216019081111561226457612264612d7b565b82815260406020820152600061311160408301846125da565b949350505050565b60006020828403121561312b57600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461263357600080fd5b6001600160a01b0384168152826020820152606060408201526000612e1360608301846125da56fea2646970667358221220f2d50ac7cf109448ada9fff306a728e5251fe66a1c6e6ec31ba9ad713c2ad83964736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa00000000000000000000000042042799b0de38add2a70dc996f69f98e1a85260
-----Decoded View---------------
Arg [0] : _serviceRegistry (address): 0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA
Arg [1] : _serviceRegistryTokenUtility (address): 0x3Fb926116D454b95c669B6Bf2E7c3bad8d19affA
Arg [2] : _operatorWhitelist (address): 0x42042799B0DE38AdD2a70dc996f69f98E1a85260
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000048b6af7b12c71f09e2fc8af4855de4ff54e775ca
Arg [1] : 0000000000000000000000003fb926116d454b95c669b6bf2e7c3bad8d19affa
Arg [2] : 00000000000000000000000042042799b0de38add2a70dc996f69f98e1a85260
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.