Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 209 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Create | 23933107 | 88 days ago | IN | 0 ETH | 0.00000816 | ||||
| Create | 23667497 | 126 days ago | IN | 0 ETH | 0.00061341 | ||||
| Deploy | 23397508 | 163 days ago | IN | 0 ETH | 0.00021645 | ||||
| Register Agents | 23397504 | 163 days ago | IN | 5 wei | 0.00009451 | ||||
| Register Agents | 23358919 | 169 days ago | IN | 0.00000001 ETH | 0.00054679 | ||||
| Activate Registr... | 23358904 | 169 days ago | IN | 0.00000001 ETH | 0.000146 | ||||
| Create | 23358878 | 169 days ago | IN | 0 ETH | 0.00057609 | ||||
| Update | 23357749 | 169 days ago | IN | 0 ETH | 0.00001004 | ||||
| Activate Registr... | 23357679 | 169 days ago | IN | 5 wei | 0.00001134 | ||||
| Activate Registr... | 23320206 | 174 days ago | IN | 0.001 ETH | 0.00017144 | ||||
| Create | 23320194 | 174 days ago | IN | 0 ETH | 0.00072364 | ||||
| Create | 23292240 | 178 days ago | IN | 0 ETH | 0.00008276 | ||||
| Create | 23291988 | 178 days ago | IN | 0 ETH | 0.00002129 | ||||
| Deploy | 22801910 | 247 days ago | IN | 0 ETH | 0.00098269 | ||||
| Register Agents | 22801904 | 247 days ago | IN | 0.00000001 ETH | 0.00047946 | ||||
| Register Agents | 22798634 | 247 days ago | IN | 0.00000001 ETH | 0.00017912 | ||||
| Activate Registr... | 22798628 | 247 days ago | IN | 0.00000001 ETH | 0.00014512 | ||||
| Create | 22798538 | 247 days ago | IN | 0 ETH | 0.00059825 | ||||
| Deploy | 22784488 | 249 days ago | IN | 0 ETH | 0.00166263 | ||||
| Register Agents | 22784452 | 249 days ago | IN | 0.00000001 ETH | 0.00077964 | ||||
| Activate Registr... | 22784353 | 249 days ago | IN | 0.00000001 ETH | 0.00021777 | ||||
| Create | 22784334 | 249 days ago | IN | 0 ETH | 0.00091287 | ||||
| Deploy | 22617399 | 272 days ago | IN | 0 ETH | 0.00258466 | ||||
| Register Agents | 22617392 | 272 days ago | IN | 0.00000001 ETH | 0.00123758 | ||||
| Activate Registr... | 22617388 | 272 days ago | IN | 0.00000001 ETH | 0.00028902 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Register Agents | 23397504 | 163 days ago | 5 wei | ||||
| Register Agents | 23358919 | 169 days ago | 0.00000001 ETH | ||||
| Activate Registr... | 23358904 | 169 days ago | 0.00000001 ETH | ||||
| Activate Registr... | 23357679 | 169 days ago | 5 wei | ||||
| Activate Registr... | 23320206 | 174 days ago | 0.001 ETH | ||||
| Register Agents | 22801904 | 247 days ago | 0.00000001 ETH | ||||
| Register Agents | 22798634 | 247 days ago | 0.00000001 ETH | ||||
| Activate Registr... | 22798628 | 247 days ago | 0.00000001 ETH | ||||
| Register Agents | 22784452 | 249 days ago | 0.00000001 ETH | ||||
| Activate Registr... | 22784353 | 249 days ago | 0.00000001 ETH | ||||
| Register Agents | 22617392 | 272 days ago | 0.00000001 ETH | ||||
| Activate Registr... | 22617388 | 272 days ago | 0.00000001 ETH | ||||
| Register Agents | 22456365 | 295 days ago | 0.005 ETH | ||||
| Register Agents | 22455971 | 295 days ago | 0.005 ETH | ||||
| Activate Registr... | 22455931 | 295 days ago | 0.005 ETH | ||||
| Activate Registr... | 22455184 | 295 days ago | 0.001 ETH | ||||
| Activate Registr... | 22453845 | 295 days ago | 0.005 ETH | ||||
| Register Agents | 21994244 | 360 days ago | 1 wei | ||||
| Activate Registr... | 21994223 | 360 days ago | 1 wei | ||||
| Register Agents | 21975880 | 362 days ago | 1 wei | ||||
| Activate Registr... | 21975872 | 362 days ago | 1 wei | ||||
| Register Agents | 21952919 | 365 days ago | 0 ETH | ||||
| Activate Registr... | 21952533 | 365 days ago | 0 ETH | ||||
| Register Agents | 21882517 | 375 days ago | 2 wei | ||||
| Activate Registr... | 21882485 | 375 days ago | 1 wei |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
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 - <aleksandr.kuperman@valory.xyz>
/// @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 - <aleksandr.kuperman@valory.xyz>
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 - <aleksandr.kuperman@valory.xyz>
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
Contract ABI
API[{"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
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.