Polygon Sponsored slots available. Book your slot here!
Overview
POL Balance
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
AttestationsRegistry
Compiler Version
v0.8.14+commit.80d49f37
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; import {IAttestationsRegistry} from './interfaces/IAttestationsRegistry.sol'; import {AttestationsRegistryConfigLogic} from './libs/attestations-registry/AttestationsRegistryConfigLogic.sol'; import {AttestationsRegistryState} from './libs/attestations-registry/AttestationsRegistryState.sol'; import {Range, RangeUtils} from './libs/utils/RangeLib.sol'; import {Attestation, AttestationData} from './libs/Structs.sol'; import {IBadges} from './interfaces/IBadges.sol'; /** * @title Attestations Registry * @author Sismo * @notice Main contract of Sismo, stores all recorded attestations in attestations collections * Only authorized attestations issuers can record attestation in the registry * Attesters that expect to record in the Attestations Registry must be authorized issuers * For more information: https://attestations-registry.docs.sismo.io * For each attestation recorded, a badge is received by the user * The badge is the Non transferrable NFT representation of an attestation * Its ERC1155 contract is stateless, balances are read directly from the registry. Badge balances <=> Attestations values * After the creation or update of an attestation, the registry triggers a TransferSingle event from the ERC1155 Badges contracts * It enables off-chain apps such as opensea to catch the "shadow mint" of the badge **/ contract AttestationsRegistry is AttestationsRegistryState, IAttestationsRegistry, AttestationsRegistryConfigLogic { IBadges immutable BADGES; /** * @dev Constructor. * @param owner Owner of the contract, has the right to authorize/unauthorize attestations issuers * @param badgesAddress Stateless ERC1155 Badges contract */ constructor(address owner, address badgesAddress) { initialize(owner); BADGES = IBadges(badgesAddress); } /** * @dev Initialize function, to be called by the proxy delegating calls to this implementation * @param owner Owner of the contract, has the right to authorize/unauthorize attestations issuers */ function initialize(address owner) public initializer { _transferOwnership(owner); } /** * @dev Main function to be called by authorized issuers * @param attestations Attestations to be recorded (creates a new one or overrides an existing one) */ function recordAttestations(Attestation[] calldata attestations) external override whenNotPaused { address issuer = _msgSender(); for (uint256 i = 0; i < attestations.length; i++) { if (!_isAuthorized(issuer, attestations[i].collectionId)) revert IssuerNotAuthorized(issuer, attestations[i].collectionId); uint256 previousAttestationValue = _attestationsData[attestations[i].collectionId][ attestations[i].owner ].value; _attestationsData[attestations[i].collectionId][attestations[i].owner] = AttestationData( attestations[i].issuer, attestations[i].value, attestations[i].timestamp, attestations[i].extraData ); _triggerBadgeTransferEvent( attestations[i].collectionId, attestations[i].owner, previousAttestationValue, attestations[i].value ); emit AttestationRecorded(attestations[i]); } } /** * @dev Delete function to be called by authorized issuers * @param attestations Attestations to be deleted */ function deleteAttestations(Attestation[] memory attestations) external override whenNotPaused { address issuer = _msgSender(); for (uint256 i = 0; i < attestations.length; i++) { uint256 previousAttestationValue = _attestationsData[attestations[i].collectionId][ attestations[i].owner ].value; if (!_isAuthorized(issuer, attestations[i].collectionId)) revert IssuerNotAuthorized(issuer, attestations[i].collectionId); delete _attestationsData[attestations[i].collectionId][attestations[i].owner]; _triggerBadgeTransferEvent( attestations[i].collectionId, attestations[i].owner, previousAttestationValue, 0 ); emit AttestationDeleted( Attestation( attestations[i].collectionId, attestations[i].owner, attestations[i].issuer, attestations[i].value, attestations[i].timestamp, attestations[i].extraData ) ); } } /** * @dev Returns whether a user has an attestation from a collection * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function hasAttestation(uint256 collectionId, address owner) external view override returns (bool) { return _getAttestationValue(collectionId, owner) != 0; } /** * @dev Getter of the data of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationData(uint256 collectionId, address owner) external view override returns (AttestationData memory) { return _getAttestationData(collectionId, owner); } /** * @dev Getter of the value of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationValue(uint256 collectionId, address owner) external view override returns (uint256) { return _getAttestationValue(collectionId, owner); } /** * @dev Getter of the data of a specific attestation as tuple * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationDataTuple(uint256 collectionId, address owner) external view override returns ( address, uint256, uint32, bytes memory ) { AttestationData memory attestationData = _attestationsData[collectionId][owner]; return ( attestationData.issuer, attestationData.value, attestationData.timestamp, attestationData.extraData ); } /** * @dev Getter of the extraData of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationExtraData(uint256 collectionId, address owner) external view override returns (bytes memory) { return _attestationsData[collectionId][owner].extraData; } /** * @dev Getter of the issuer of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationIssuer(uint256 collectionId, address owner) external view override returns (address) { return _attestationsData[collectionId][owner].issuer; } /** * @dev Getter of the timestamp of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationTimestamp(uint256 collectionId, address owner) external view override returns (uint32) { return _attestationsData[collectionId][owner].timestamp; } /** * @dev Getter of the data of specific attestations * @param collectionIds Collection identifiers of the targeted attestations * @param owners Owners of the targeted attestations */ function getAttestationDataBatch(uint256[] memory collectionIds, address[] memory owners) external view override returns (AttestationData[] memory) { AttestationData[] memory attestationsDataArray = new AttestationData[](collectionIds.length); for (uint256 i = 0; i < collectionIds.length; i++) { attestationsDataArray[i] = _getAttestationData(collectionIds[i], owners[i]); } return attestationsDataArray; } /** * @dev Getter of the values of specific attestations * @param collectionIds Collection identifiers of the targeted attestations * @param owners Owners of the targeted attestations */ function getAttestationValueBatch(uint256[] memory collectionIds, address[] memory owners) external view override returns (uint256[] memory) { uint256[] memory attestationsValues = new uint256[](collectionIds.length); for (uint256 i = 0; i < collectionIds.length; i++) { attestationsValues[i] = _getAttestationValue(collectionIds[i], owners[i]); } return attestationsValues; } /** * @dev Function that trigger a TransferSingle event from the stateless ERC1155 Badges contract * It enables off-chain apps such as opensea to catch the "shadow mints/burns" of badges */ function _triggerBadgeTransferEvent( uint256 badgeTokenId, address owner, uint256 previousValue, uint256 newValue ) internal { bool isGreaterValue = newValue > previousValue; address operator = address(this); address from = isGreaterValue ? address(0) : owner; address to = isGreaterValue ? owner : address(0); uint256 value = isGreaterValue ? newValue - previousValue : previousValue - newValue; // if isGreaterValue is true, function triggers mint event. Otherwise triggers burn event. BADGES.triggerTransferEvent(operator, from, to, badgeTokenId, value); } function _getAttestationData(uint256 collectionId, address owner) internal view returns (AttestationData memory) { return (_attestationsData[collectionId][owner]); } function _getAttestationValue(uint256 collectionId, address owner) internal view returns (uint256) { return _attestationsData[collectionId][owner].value; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; import {Attestation, AttestationData} from '../libs/Structs.sol'; /** * @title IAttestationsRegistry * @author Sismo * @notice This is the interface of the AttestationRegistry */ interface IAttestationsRegistry { event AttestationRecorded(Attestation attestation); event AttestationDeleted(Attestation attestation); /** * @dev Main function to be called by authorized issuers * @param attestations Attestations to be recorded (creates a new one or overrides an existing one) */ function recordAttestations(Attestation[] calldata attestations) external; /** * @dev Delete function to be called by authorized issuers * @param attestations Attestations to be deleted */ function deleteAttestations(Attestation[] calldata attestations) external; /** * @dev Returns whether a user has an attestation from a collection * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function hasAttestation(uint256 collectionId, address owner) external returns (bool); /** * @dev Getter of the data of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationData(uint256 collectionId, address owner) external view returns (AttestationData memory); /** * @dev Getter of the value of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationValue(uint256 collectionId, address owner) external view returns (uint256); /** * @dev Getter of the data of a specific attestation as tuple * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationDataTuple(uint256 collectionId, address owner) external view returns ( address, uint256, uint32, bytes memory ); /** * @dev Getter of the extraData of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationExtraData(uint256 collectionId, address owner) external view returns (bytes memory); /** * @dev Getter of the issuer of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationIssuer(uint256 collectionId, address owner) external view returns (address); /** * @dev Getter of the timestamp of a specific attestation * @param collectionId Collection identifier of the targeted attestation * @param owner Owner of the targeted attestation */ function getAttestationTimestamp(uint256 collectionId, address owner) external view returns (uint32); /** * @dev Getter of the data of specific attestations * @param collectionIds Collection identifiers of the targeted attestations * @param owners Owners of the targeted attestations */ function getAttestationDataBatch(uint256[] memory collectionIds, address[] memory owners) external view returns (AttestationData[] memory); /** * @dev Getter of the values of specific attestations * @param collectionIds Collection identifiers of the targeted attestations * @param owners Owners of the targeted attestations */ function getAttestationValueBatch(uint256[] memory collectionIds, address[] memory owners) external view returns (uint256[] memory); }
// SPDX-License-Identifier: MIT // Forked from, removed storage, OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.14; import {Range, RangeUtils} from '../libs/utils/RangeLib.sol'; interface IAttestationsRegistryConfigLogic { error IssuerNotAuthorized(address issuer, uint256 collectionId); error AttesterNotFound(address issuer); error RangeIndexOutOfBounds(address issuer, uint256 expectedArrayLength, uint256 rangeIndex); error IdsMismatch( address issuer, uint256 rangeIndex, uint256 expectedFirstId, uint256 expectedLastId, uint256 FirstId, uint256 lastCollectionId ); event IssuerAuthorized(address issuer, uint256 firstCollectionId, uint256 lastCollectionId); event IssuerUnauthorized(address issuer, uint256 firstCollectionId, uint256 lastCollectionId); /** * @dev Authorize an issuer for a specific range * @param issuer Issuer that will be authorized * @param firstCollectionId First collection Id of the range for which the issuer will be authorized * @param lastCollectionId Last collection Id of the range for which the issuer will be authorized */ function authorizeRange( address issuer, uint256 firstCollectionId, uint256 lastCollectionId ) external; /** * @dev Unauthorize an issuer for a specific range * @param issuer Issuer that will be unauthorized * @param rangeIndex Index of the range to be unauthorized * @param firstCollectionId First collection Id of the range for which the issuer will be unauthorized * @param lastCollectionId Last collection Id of the range for which the issuer will be unauthorized */ function unauthorizeRange( address issuer, uint256 rangeIndex, uint256 firstCollectionId, uint256 lastCollectionId ) external; /** * @dev Authorize an issuer for specific ranges * @param issuer Issuer that will be authorized * @param ranges Ranges for which the issuer will be authorized */ function authorizeRanges(address issuer, Range[] memory ranges) external; /** * @dev Unauthorize an issuer for specific ranges * @param issuer Issuer that will be unauthorized * @param ranges Ranges for which the issuer will be unauthorized */ function unauthorizeRanges( address issuer, Range[] memory ranges, uint256[] memory rangeIndexes ) external; /** * @dev Returns whether a specific issuer is authorized or not to record in a specific attestations collection * @param issuer Issuer to be checked * @param collectionId Collection Id for which the issuer will be checked */ function isAuthorized(address issuer, uint256 collectionId) external view returns (bool); /** * @dev Pauses the registry. Issuers can no longer record or delete attestations */ function pause() external; /** * @dev Unpauses the registry */ function unpause() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; /** * @title Interface for Badges contract * @author Sismo * @notice Stateless ERC1155 contract. Reads balance from the values of attestations * The associated attestations registry triggers TransferSingle events from this contract * It allows badge "shadow mints and burns" to be caught by off-chain platforms */ interface IBadges { error BadgesNonTransferrable(); /** * @dev Initializes the contract, to be called by the proxy delegating calls to this implementation * @param uri Uri for the metadata of badges * @param owner Owner of the contract, super admin, can setup roles and update the attestation registry */ function initialize(string memory uri, address owner) external; /** * @dev Main function of the ERC1155 badge * The balance of a user is equal to the value of the underlying attestation. * attestationCollectionId == badgeId * @param account Address to check badge balance (= value of attestation) * @param id Badge Id to check (= attestationCollectionId) */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev Emits a TransferSingle event, so subgraphs and other off-chain apps relying on events can see badge minting/burning * can only be called by address having the EVENT_TRIGGERER_ROLE (attestations registry address) * @param operator who is calling the TransferEvent * @param from address(0) if minting, address of the badge holder if burning * @param to address of the badge holder is minting, address(0) if burning * @param id badgeId for which to trigger the event * @param value minted/burned balance */ function triggerTransferEvent( address operator, address from, address to, uint256 id, uint256 value ) external; /** * @dev Set the attestations registry address. Can only be called by owner (default admin) * @param attestationsRegistry new attestations registry address */ function setAttestationsRegistry(address attestationsRegistry) external; /** * @dev Set the URI. Can only be called by owner (default admin) * @param uri new attestations registry address */ function setUri(string memory uri) external; /** * @dev Getter of the attestations registry */ function getAttestationsRegistry() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; /** * @title Attestations Registry State * @author Sismo * @notice This contract holds all of the storage variables and data * structures used by the AttestationsRegistry and parent * contracts. */ // User Attestation Request, can be made by any user // The context of an Attestation Request is a specific attester contract // Each attester has groups of accounts in its available data // eg: for a specific attester: // group 1 <=> accounts that sent txs on mainnet // group 2 <=> accounts that sent txs on polygon // eg: for another attester: // group 1 <=> accounts that sent eth txs in 2022 // group 2 <=> accounts sent eth txs in 2021 struct Request { // implicit address attester; // implicit uint256 chainId; Claim[] claims; address destination; // destination that will receive the end attestation } struct Claim { uint256 groupId; // user claims to have an account in this group uint256 claimedValue; // user claims this value for its account in the group bytes extraData; // arbitrary data, may be required by the attester to verify claims or generate a specific attestation } /** * @dev Attestation Struct. This is the struct receive as argument by the Attestation Registry. * @param collectionId Attestation collection * @param owner Attestation collection * @param issuer Attestation collection * @param value Attestation collection * @param timestamp Attestation collection * @param extraData Attestation collection */ struct Attestation { // implicit uint256 chainId; uint256 collectionId; // Id of the attestation collection (in the registry) address owner; // Owner of the attestation address issuer; // Contract that created or last updated the record. uint256 value; // Value of the attestation uint32 timestamp; // Timestamp chosen by the attester, should correspond to the effective date of the attestation // it is different from the recording timestamp (date when the attestation was recorded) // e.g a proof of NFT ownership may have be recorded today which is 2 month old data. bytes extraData; // arbitrary data that can be added by the attester } // Attestation Data, stored in the registry // The context is a specific owner of a specific collection struct AttestationData { // implicit uint256 chainId // implicit uint256 collectionId - from context // implicit owner address issuer; // Address of the contract that recorded the attestation uint256 value; // Value of the attestation uint32 timestamp; // Effective date of issuance of the attestation. (can be different from the recording timestamp) bytes extraData; // arbitrary data that can be added by the attester }
// SPDX-License-Identifier: MIT // Forked from, removed storage, OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.14; import './OwnableLogic.sol'; import './PausableLogic.sol'; import './InitializableLogic.sol'; import './AttestationsRegistryState.sol'; import {IAttestationsRegistryConfigLogic} from './../../interfaces/IAttestationsRegistryConfigLogic.sol'; import {Range, RangeUtils} from '../utils/RangeLib.sol'; /** * @title Attestations Registry Config Logic contract * @author Sismo * @notice Holds the logic of how to authorize/ unauthorize issuers of attestations in the registry **/ contract AttestationsRegistryConfigLogic is AttestationsRegistryState, IAttestationsRegistryConfigLogic, OwnableLogic, PausableLogic, InitializableLogic { using RangeUtils for Range[]; /** * @dev Authorize an issuer for a specific range * @param issuer Issuer that will be authorized * @param firstCollectionId First collection Id of the range for which the issuer will be authorized * @param lastCollectionId Last collection Id of the range for which the issuer will be authorized */ function authorizeRange( address issuer, uint256 firstCollectionId, uint256 lastCollectionId ) external override onlyOwner { _authorizeRange(issuer, firstCollectionId, lastCollectionId); } /** * @dev Unauthorize an issuer for a specific range * @param issuer Issuer that will be unauthorized * @param rangeIndex Index of the range to be unauthorized * @param firstCollectionId First collection Id of the range for which the issuer will be unauthorized * @param lastCollectionId Last collection Id of the range for which the issuer will be unauthorized */ function unauthorizeRange( address issuer, uint256 rangeIndex, uint256 firstCollectionId, uint256 lastCollectionId ) external override onlyOwner { _unauthorizeRange(issuer, rangeIndex, firstCollectionId, lastCollectionId); } /** * @dev Authorize an issuer for specific ranges * @param issuer Issuer that will be authorized * @param ranges Ranges for which the issuer will be authorized */ function authorizeRanges(address issuer, Range[] memory ranges) external override onlyOwner { for (uint256 i = 0; i < ranges.length; i++) { _authorizeRange(issuer, ranges[i].min, ranges[i].max); } } /** * @dev Unauthorize an issuer for specific ranges * @param issuer Issuer that will be unauthorized * @param ranges Ranges for which the issuer will be unauthorized */ function unauthorizeRanges( address issuer, Range[] memory ranges, uint256[] memory rangeIndexes ) external override onlyOwner { for (uint256 i = 0; i < rangeIndexes.length; i++) { _unauthorizeRange(issuer, rangeIndexes[i] - i, ranges[i].min, ranges[i].max); } } /** * @dev Returns whether a specific issuer is authorized or not to record in a specific attestations collection * @param issuer Issuer to be checked * @param collectionId Collection Id for which the issuer will be checked */ function isAuthorized(address issuer, uint256 collectionId) external view returns (bool) { return _isAuthorized(issuer, collectionId); } /** * @dev Pauses the registry. Issuers can no longer record or delete attestations */ function pause() external override onlyOwner { _pause(); } /** * @dev Unpauses the registry */ function unpause() external override onlyOwner { _unpause(); } function _isAuthorized(address issuer, uint256 collectionId) internal view returns (bool) { return _authorizedRanges[issuer]._includes(collectionId); } function _authorizeRange( address issuer, uint256 firstCollectionId, uint256 lastCollectionId ) internal { Range memory newRange = Range(firstCollectionId, lastCollectionId); _authorizedRanges[issuer].push(newRange); emit IssuerAuthorized(issuer, firstCollectionId, lastCollectionId); } function _unauthorizeRange( address issuer, uint256 rangeIndex, uint256 firstCollectionId, uint256 lastCollectionId ) internal onlyOwner { if (rangeIndex >= _authorizedRanges[issuer].length) revert RangeIndexOutOfBounds(issuer, _authorizedRanges[issuer].length, rangeIndex); uint256 expectedFirstId = _authorizedRanges[issuer][rangeIndex].min; uint256 expectedLastId = _authorizedRanges[issuer][rangeIndex].max; if (firstCollectionId != expectedFirstId || lastCollectionId != expectedLastId) revert IdsMismatch( issuer, rangeIndex, expectedFirstId, expectedLastId, firstCollectionId, lastCollectionId ); _authorizedRanges[issuer][rangeIndex] = _authorizedRanges[issuer][ _authorizedRanges[issuer].length - 1 ]; _authorizedRanges[issuer].pop(); emit IssuerUnauthorized(issuer, firstCollectionId, lastCollectionId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; import {Range} from '../utils/RangeLib.sol'; import {Attestation, AttestationData} from '../Structs.sol'; contract AttestationsRegistryState { // main config bool internal _initialized; bool internal _initializing; bool internal _paused; address internal _owner; // keeping some space for future uint256[15] private _placeHolders; // storing the authorized ranges for each attesters mapping(address => Range[]) internal _authorizedRanges; // keeping some space for future uint256[15] private _placeHolders2; // storing the data of attestations // =collectionId=> =owner=> attestationData mapping(uint256 => mapping(address => AttestationData)) internal _attestationsData; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) // Forked from, removed storage, OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.14; import '../utils/Address.sol'; import './AttestationsRegistryState.sol'; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract InitializableLogic is AttestationsRegistryState { // only diff with oz // /** // * @dev Indicates that the contract has been initialized. // */ // bool private _initialized; // /** // * @dev Indicates that the contract is in the process of being initialized. // */ // bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require( _initializing ? _isConstructor() : !_initialized, 'Initializable: contract is already initialized' ); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, 'Initializable: contract is not initializing'); _; } function _isConstructor() private view returns (bool) { return !Address.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // Forked from, removed storage, OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.14; import '../utils/Context.sol'; import './AttestationsRegistryState.sol'; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableLogic is Context, AttestationsRegistryState { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // This is the only diff with OZ contract // address private _owner; /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'Ownable: new owner is the zero address'); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // Forked from, removed storage, OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.14; import '../utils/Context.sol'; import './AttestationsRegistryState.sol'; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableLogic is Context, AttestationsRegistryState { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); // this is the only diff with OZ contract // bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), 'Pausable: paused'); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), 'Pausable: not paused'); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, 'Address: low-level delegate call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.14; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.14; struct Range { uint256 min; uint256 max; } // Range [0;3] includees 0 and 3 library RangeUtils { function _includes(Range[] storage ranges, uint256 collectionId) internal view returns (bool) { for (uint256 i = 0; i < ranges.length; i++) { if (collectionId >= ranges[i].min && collectionId <= ranges[i].max) { return true; } } return false; } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"badgesAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"AttesterNotFound","type":"error"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"internalType":"uint256","name":"expectedFirstId","type":"uint256"},{"internalType":"uint256","name":"expectedLastId","type":"uint256"},{"internalType":"uint256","name":"FirstId","type":"uint256"},{"internalType":"uint256","name":"lastCollectionId","type":"uint256"}],"name":"IdsMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"collectionId","type":"uint256"}],"name":"IssuerNotAuthorized","type":"error"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"expectedArrayLength","type":"uint256"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"}],"name":"RangeIndexOutOfBounds","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"indexed":false,"internalType":"struct Attestation","name":"attestation","type":"tuple"}],"name":"AttestationDeleted","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"indexed":false,"internalType":"struct Attestation","name":"attestation","type":"tuple"}],"name":"AttestationRecorded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"issuer","type":"address"},{"indexed":false,"internalType":"uint256","name":"firstCollectionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastCollectionId","type":"uint256"}],"name":"IssuerAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"issuer","type":"address"},{"indexed":false,"internalType":"uint256","name":"firstCollectionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastCollectionId","type":"uint256"}],"name":"IssuerUnauthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"firstCollectionId","type":"uint256"},{"internalType":"uint256","name":"lastCollectionId","type":"uint256"}],"name":"authorizeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"internalType":"struct Range[]","name":"ranges","type":"tuple[]"}],"name":"authorizeRanges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Attestation[]","name":"attestations","type":"tuple[]"}],"name":"deleteAttestations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationData","outputs":[{"components":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AttestationData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"collectionIds","type":"uint256[]"},{"internalType":"address[]","name":"owners","type":"address[]"}],"name":"getAttestationDataBatch","outputs":[{"components":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AttestationData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationDataTuple","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationExtraData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationIssuer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"getAttestationValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"collectionIds","type":"uint256[]"},{"internalType":"address[]","name":"owners","type":"address[]"}],"name":"getAttestationValueBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"hasAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"collectionId","type":"uint256"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"components":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Attestation[]","name":"attestations","type":"tuple[]"}],"name":"recordAttestations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"internalType":"uint256","name":"firstCollectionId","type":"uint256"},{"internalType":"uint256","name":"lastCollectionId","type":"uint256"}],"name":"unauthorizeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"internalType":"struct Range[]","name":"ranges","type":"tuple[]"},{"internalType":"uint256[]","name":"rangeIndexes","type":"uint256[]"}],"name":"unauthorizeRanges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200288f3803806200288f8339810160408190526200003491620001e4565b6200003f3362000069565b6000805462ff0000191690556200005682620000c6565b6001600160a01b0316608052506200021c565b600080546001600160a01b0383811663010000008181026301000000600160b81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600054610100900460ff16620000e35760005460ff1615620000ed565b620000ed6200019a565b620001555760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff1615801562000178576000805461ffff19166101011790555b620001838262000069565b801562000196576000805461ff00191690555b5050565b6000620001b230620001b860201b6200133c1760201c565b15905090565b6001600160a01b03163b151590565b80516001600160a01b0381168114620001df57600080fd5b919050565b60008060408385031215620001f857600080fd5b6200020383620001c7565b91506200021360208401620001c7565b90509250929050565b6080516126576200023860003960006119b801526126576000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638456cb59116100c3578063c4d66de81161007c578063c4d66de814610326578063c7da9aa614610339578063dc873d011461036e578063e7c994361461038e578063ebc5c093146103a1578063f2fde38b146103b457600080fd5b80638456cb591461028b57806384c2ad82146102935780638c3c9e32146102b35780638da5cb5b146102d4578063b886567314610300578063c06d5db61461031357600080fd5b80633be1ced7116101155780633be1ced7146102145780633f4ba83a146102375780635c975abb1461023f5780636d7fbb6714610250578063715018a6146102705780637cde0fe21461027857600080fd5b8063011023901461015257806314067f8b1461017a57806315027bda146101cc578063181dfdff146101ec5780632972b0f014610201575b600080fd5b610165610160366004611b9e565b6103c7565b60405190151581526020015b60405180910390f35b6101b7610188366004611b9e565b6000918252602080805260408084206001600160a01b0393909316845291905290206002015463ffffffff1690565b60405163ffffffff9091168152602001610171565b6101df6101da366004611ce8565b6103de565b6040516101719190611e3f565b6101ff6101fa366004611f20565b6104cf565b005b61016561020f366004611f93565b610598565b610227610222366004611b9e565b6105ab565b6040516101719493929190611fbd565b6101ff6106c1565b60005462010000900460ff16610165565b61026361025e366004611b9e565b6106fd565b6040516101719190611ffa565b6101ff6107b5565b6101ff61028636600461200d565b6107f1565b6101ff610833565b6102a66102a1366004611b9e565b61086d565b6040516101719190612040565b6102c66102c1366004611b9e565b61089a565b604051908152602001610171565b600054630100000090046001600160a01b03165b6040516001600160a01b039091168152602001610171565b6101ff61030e366004612053565b6108a6565b6101ff6103213660046120a0565b61093b565b6101ff6103343660046120d9565b610979565b6102e8610347366004611b9e565b6000918252602080805260408084206001600160a01b039384168552909152909120541690565b61038161037c366004611ce8565b610a3c565b60405161017191906120f4565b6101ff61039c36600461214c565b610afc565b6101ff6103af3660046122d3565b610e41565b6101ff6103c23660046120d9565b611299565b60006103d3838361134b565b151590505b92915050565b6060600083516001600160401b038111156103fb576103fb611bca565b60405190808252806020026020018201604052801561044c57816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816104195790505b50905060005b84518110156104c75761049785828151811061047057610470612347565b602002602001015185838151811061048a5761048a612347565b6020026020010151611374565b8282815181106104a9576104a9612347565b602002602001018190525080806104bf90612373565b915050610452565b509392505050565b6000546001600160a01b03630100000090910416331461050a5760405162461bcd60e51b81526004016105019061238c565b60405180910390fd5b60005b815181101561059257610580848284848151811061052d5761052d612347565b602002602001015161053f91906123c1565b85848151811061055157610551612347565b60200260200101516000015186858151811061056f5761056f612347565b602002602001015160200151611483565b8061058a81612373565b91505061050d565b50505050565b60006105a48383611722565b9392505050565b6000828152602080805260408083206001600160a01b038086168552908352818420825160808101845281549092168252600181015493820193909352600283015463ffffffff1691810191909152600382018054849384936060938593919291838601919061061a906123d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610646906123d8565b80156106935780601f1061066857610100808354040283529160200191610693565b820191906000526020600020905b81548152906001019060200180831161067657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000546001600160a01b0363010000009091041633146106f35760405162461bcd60e51b81526004016105019061238c565b6106fb611744565b565b6000828152602080805260408083206001600160a01b0385168452909152902060030180546060919061072f906123d8565b80601f016020809104026020016040519081016040528092919081815260200182805461075b906123d8565b80156107a85780601f1061077d576101008083540402835291602001916107a8565b820191906000526020600020905b81548152906001019060200180831161078b57829003601f168201915b5050505050905092915050565b6000546001600160a01b0363010000009091041633146107e75760405162461bcd60e51b81526004016105019061238c565b6106fb60006117df565b6000546001600160a01b0363010000009091041633146108235760405162461bcd60e51b81526004016105019061238c565b61082e83838361183c565b505050565b6000546001600160a01b0363010000009091041633146108655760405162461bcd60e51b81526004016105019061238c565b6106fb6118ce565b60408051608081018252600080825260208201819052918101919091526060808201526105a48383611374565b60006105a4838361134b565b6000546001600160a01b0363010000009091041633146108d85760405162461bcd60e51b81526004016105019061238c565b60005b815181101561082e57610929838383815181106108fa576108fa612347565b60200260200101516000015184848151811061091857610918612347565b60200260200101516020015161183c565b8061093381612373565b9150506108db565b6000546001600160a01b03630100000090910416331461096d5760405162461bcd60e51b81526004016105019061238c565b61059284848484611483565b600054610100900460ff166109945760005460ff1615610998565b303b155b6109fb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610501565b600054610100900460ff16158015610a1d576000805461ffff19166101011790555b610a26826117df565b8015610a38576000805461ff00191690555b5050565b6060600083516001600160401b03811115610a5957610a59611bca565b604051908082528060200260200182016040528015610a82578160200160208202803683370190505b50905060005b84518110156104c757610acd858281518110610aa657610aa6612347565b6020026020010151858381518110610ac057610ac0612347565b602002602001015161134b565b828281518110610adf57610adf612347565b602090810291909101015280610af481612373565b915050610a88565b60005462010000900460ff1615610b255760405162461bcd60e51b815260040161050190612412565b3360005b825181101561082e57600060206000858481518110610b4a57610b4a612347565b60200260200101516000015181526020019081526020016000206000858481518110610b7857610b78612347565b6020026020010151602001516001600160a01b03166001600160a01b03168152602001908152602001600020600101549050610bd183858481518110610bc057610bc0612347565b602002602001015160000151611722565b610c1e5782848381518110610be857610be8612347565b60209081029190910101515160405163c522f21160e01b81526001600160a01b0390921660048301526024820152604401610501565b60206000858481518110610c3457610c34612347565b60200260200101516000015181526020019081526020016000206000858481518110610c6257610c62612347565b6020908102919091018101518101516001600160a01b03168252810191909152604001600090812080546001600160a01b03191681556001810182905560028101805463ffffffff1916905590610cbc6003830182611aaf565b5050610d05848381518110610cd357610cd3612347565b602002602001015160000151858481518110610cf157610cf1612347565b602002602001015160200151836000611930565b7f01cba57fa881d11e8be5640b6abefb9709f2dd45f776051b2cf5cb8ea23fa56b6040518060c00160405280868581518110610d4357610d43612347565b6020026020010151600001518152602001868581518110610d6657610d66612347565b6020026020010151602001516001600160a01b03168152602001868581518110610d9257610d92612347565b6020026020010151604001516001600160a01b03168152602001868581518110610dbe57610dbe612347565b6020026020010151606001518152602001868581518110610de157610de1612347565b60200260200101516080015163ffffffff168152602001868581518110610e0a57610e0a612347565b602002602001015160a00151815250604051610e26919061243c565b60405180910390a15080610e3981612373565b915050610b29565b60005462010000900460ff1615610e6a5760405162461bcd60e51b815260040161050190612412565b3360005b8281101561059257610ea482858584818110610e8c57610e8c612347565b9050602002810190610e9e919061249d565b35611722565b610ef85781848483818110610ebb57610ebb612347565b9050602002810190610ecd919061249d565b60405163c522f21160e01b81526001600160a01b039092166004830152356024820152604401610501565b600060206000868685818110610f1057610f10612347565b9050602002810190610f22919061249d565b6000013581526020019081526020016000206000868685818110610f4857610f48612347565b9050602002810190610f5a919061249d565b610f6b9060408101906020016120d9565b6001600160a01b03166001600160a01b031681526020019081526020016000206001015490506040518060800160405280868685818110610fae57610fae612347565b9050602002810190610fc0919061249d565b610fd19060608101906040016120d9565b6001600160a01b03168152602001868685818110610ff157610ff1612347565b9050602002810190611003919061249d565b60600135815260200186868581811061101e5761101e612347565b9050602002810190611030919061249d565b6110419060a08101906080016124bd565b63ffffffff16815260200186868581811061105e5761105e612347565b9050602002810190611070919061249d565b61107e9060a08101906124d8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452506020925088905087868181106110cb576110cb612347565b90506020028101906110dd919061249d565b600001358152602001908152602001600020600087878681811061110357611103612347565b9050602002810190611115919061249d565b6111269060408101906020016120d9565b6001600160a01b0390811682526020808301939093526040918201600020845181546001600160a01b03191692169190911781558383015160018201559083015160028201805463ffffffff191663ffffffff90921691909117905560608301518051919261119d92600385019290910190611ae9565b5090505061122c8585848181106111b6576111b6612347565b90506020028101906111c8919061249d565b358686858181106111db576111db612347565b90506020028101906111ed919061249d565b6111fe9060408101906020016120d9565b8388888781811061121157611211612347565b9050602002810190611223919061249d565b60600135611930565b7f8c20c3acb6b5208b7affea2fd90dabc8d47e77cee9766c855ce42730505cb20585858481811061125f5761125f612347565b9050602002810190611271919061249d565b60405161127e919061254e565b60405180910390a1508061129181612373565b915050610e6e565b6000546001600160a01b0363010000009091041633146112cb5760405162461bcd60e51b81526004016105019061238c565b6001600160a01b0381166113305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610501565b611339816117df565b50565b6001600160a01b03163b151590565b6000918252602080805260408084206001600160a01b0393909316845291905290206001015490565b60408051608081018252600080825260208201819052918101919091526060808201526000838152602080805260408083206001600160a01b03808716855290835292819020815160808101835281549094168452600181015492840192909252600282015463ffffffff16908301526003810180546060840191906113f9906123d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611425906123d8565b80156114725780601f1061144757610100808354040283529160200191611472565b820191906000526020600020905b81548152906001019060200180831161145557829003601f168201915b505050505081525050905092915050565b6000546001600160a01b0363010000009091041633146114b55760405162461bcd60e51b81526004016105019061238c565b6001600160a01b0384166000908152601060205260409020548310611517576001600160a01b038416600081815260106020526040908190205490516345e388eb60e01b81526004810192909252602482015260448101849052606401610501565b6001600160a01b038416600090815260106020526040812080548590811061154157611541612347565b600091825260208083206002909202909101546001600160a01b03881683526010909152604082208054919350908690811061157f5761157f612347565b906000526020600020906002020160010154905081841415806115a25750808314155b156115ee57604051637a4dd76560e01b81526001600160a01b03871660048201526024810186905260448101839052606481018290526084810185905260a4810184905260c401610501565b6001600160a01b03861660009081526010602052604090208054611614906001906123c1565b8154811061162457611624612347565b906000526020600020906002020160106000886001600160a01b03166001600160a01b03168152602001908152602001600020868154811061166857611668612347565b60009182526020808320845460029093020191825560019384015493909101929092556001600160a01b03881681526010909152604090208054806116af576116af61260b565b6000828152602080822060026000199490940193840201828155600101919091559155604080516001600160a01b038916815291820186905281018490527f33cff58e54c3a8acae85cad63487b5dcf617521e33bb03f071299f374c29de1f9060600160405180910390a1505050505050565b6001600160a01b03821660009081526010602052604081206105a49083611a21565b60005462010000900460ff166117935760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610501565b6000805462ff0000191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600080546001600160a01b0383811663010000008181026301000000600160b81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b60408051808201825283815260208082018481526001600160a01b03871660008181526010845285812080546001808201835591835291859020865160029093020191825592519201919091558351908152908101859052918201839052907fe7d6ac0b740347f7f96a97e6a9dc0f20f4f11eca65495315adc009a55b6762f89060600160405180910390a150505050565b60005462010000900460ff16156118f75760405162461bcd60e51b815260040161050190612412565b6000805462ff00001916620100001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117c23390565b818111306000826119415785611944565b60005b9050600083611954576000611956565b865b905060008461196e5761196986886123c1565b611978565b61197887876123c1565b604051633885984b60e11b81526001600160a01b03868116600483015285811660248301528481166044830152606482018c9052608482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063710b30969060a401600060405180830381600087803b1580156119fe57600080fd5b505af1158015611a12573d6000803e3d6000fd5b50505050505050505050505050565b6000805b8354811015611aa557838181548110611a4057611a40612347565b9060005260206000209060020201600001548310158015611a845750838181548110611a6e57611a6e612347565b9060005260206000209060020201600101548311155b15611a935760019150506103d8565b80611a9d81612373565b915050611a25565b5060009392505050565b508054611abb906123d8565b6000825580601f10611acb575050565b601f0160209004906000526020600020908101906113399190611b6d565b828054611af5906123d8565b90600052602060002090601f016020900481019282611b175760008555611b5d565b82601f10611b3057805160ff1916838001178555611b5d565b82800160010185558215611b5d579182015b82811115611b5d578251825591602001919060010190611b42565b50611b69929150611b6d565b5090565b5b80821115611b695760008155600101611b6e565b80356001600160a01b0381168114611b9957600080fd5b919050565b60008060408385031215611bb157600080fd5b82359150611bc160208401611b82565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611c0257611c02611bca565b60405290565b60405160c081016001600160401b0381118282101715611c0257611c02611bca565b604051601f8201601f191681016001600160401b0381118282101715611c5257611c52611bca565b604052919050565b60006001600160401b03821115611c7357611c73611bca565b5060051b60200190565b600082601f830112611c8e57600080fd5b81356020611ca3611c9e83611c5a565b611c2a565b82815260059290921b84018101918181019086841115611cc257600080fd5b8286015b84811015611cdd5780358352918301918301611cc6565b509695505050505050565b60008060408385031215611cfb57600080fd5b82356001600160401b0380821115611d1257600080fd5b611d1e86838701611c7d565b9350602091508185013581811115611d3557600080fd5b85019050601f81018613611d4857600080fd5b8035611d56611c9e82611c5a565b81815260059190911b82018301908381019088831115611d7557600080fd5b928401925b82841015611d9a57611d8b84611b82565b82529284019290840190611d7a565b80955050505050509250929050565b6000815180845260005b81811015611dcf57602081850181015186830182015201611db3565b81811115611de1576000602083870101525b50601f01601f19169290920160200192915050565b60018060a01b0381511682526020810151602083015263ffffffff60408201511660408301526000606082015160806060850152611e376080850182611da9565b949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611e9457603f19888603018452611e82858351611df6565b94509285019290850190600101611e66565b5092979650505050505050565b600082601f830112611eb257600080fd5b81356020611ec2611c9e83611c5a565b82815260069290921b84018101918181019086841115611ee157600080fd5b8286015b84811015611cdd5760408189031215611efe5760008081fd5b611f06611be0565b813581528482013585820152835291830191604001611ee5565b600080600060608486031215611f3557600080fd5b611f3e84611b82565b925060208401356001600160401b0380821115611f5a57600080fd5b611f6687838801611ea1565b93506040860135915080821115611f7c57600080fd5b50611f8986828701611c7d565b9150509250925092565b60008060408385031215611fa657600080fd5b611faf83611b82565b946020939093013593505050565b60018060a01b038516815283602082015263ffffffff83166040820152608060608201526000611ff06080830184611da9565b9695505050505050565b6020815260006105a46020830184611da9565b60008060006060848603121561202257600080fd5b61202b84611b82565b95602085013595506040909401359392505050565b6020815260006105a46020830184611df6565b6000806040838503121561206657600080fd5b61206f83611b82565b915060208301356001600160401b0381111561208a57600080fd5b61209685828601611ea1565b9150509250929050565b600080600080608085870312156120b657600080fd5b6120bf85611b82565b966020860135965060408601359560600135945092505050565b6000602082840312156120eb57600080fd5b6105a482611b82565b6020808252825182820181905260009190848201906040850190845b8181101561212c57835183529284019291840191600101612110565b50909695505050505050565b803563ffffffff81168114611b9957600080fd5b6000602080838503121561215f57600080fd5b82356001600160401b038082111561217657600080fd5b818501915085601f83011261218a57600080fd5b8135612198611c9e82611c5a565b81815260059190911b830184019084810190888311156121b757600080fd5b8585015b838110156122c6578035858111156121d35760008081fd5b860160c0601f19828d0381018213156121ec5760008081fd5b6121f4611c08565b8a84013581526040612207818601611b82565b8c8301526060612218818701611b82565b828401526080808701358285015260a09150612235828801612138565b9084015293850135938a85111561224c5760008081fd5b84860195508f603f87011261226357600094508485fd5b8c86013594508a85111561227957612279611bca565b6122898d85601f88011601611c2a565b93508484528f828688010111156122a05760008081fd5b848287018e86013760009484018d019490945250918201528452509186019186016121bb565b5098975050505050505050565b600080602083850312156122e657600080fd5b82356001600160401b03808211156122fd57600080fd5b818501915085601f83011261231157600080fd5b81358181111561232057600080fd5b8660208260051b850101111561233557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016123855761238561235d565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000828210156123d3576123d361235d565b500390565b600181811c908216806123ec57607f821691505b60208210810361240c57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208152815160208201526000602083015160018060a01b03808216604085015280604086015116606085015250506060830151608083015263ffffffff60808401511660a083015260a083015160c080840152611e3760e0840182611da9565b6000823560be198336030181126124b357600080fd5b9190910192915050565b6000602082840312156124cf57600080fd5b6105a482612138565b6000808335601e198436030181126124ef57600080fd5b8301803591506001600160401b0382111561250957600080fd5b60200191503681900382131561251e57600080fd5b9250929050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815281356020820152600061256760208401611b82565b60018060a01b0380821660408501528061258360408701611b82565b16606085015250506060830135608083015263ffffffff6125a660808501612138565b1660a083015260a0830135601e198436030181126125c357600080fd5b83016020810190356001600160401b038111156125df57600080fd5b8036038213156125ee57600080fd5b60c08085015261260260e085018284612525565b95945050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220c903c76a32e6925df15285171ac55d0624e9da3ca4368c9b9fa0c5e0482dd28864736f6c634300080e00330000000000000000000000009fbe1230aa270f55870dd0c631ef3f4cc54a1dda000000000000000000000000f12494e3545d49616d9dfb78e5907e9078618a34
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638456cb59116100c3578063c4d66de81161007c578063c4d66de814610326578063c7da9aa614610339578063dc873d011461036e578063e7c994361461038e578063ebc5c093146103a1578063f2fde38b146103b457600080fd5b80638456cb591461028b57806384c2ad82146102935780638c3c9e32146102b35780638da5cb5b146102d4578063b886567314610300578063c06d5db61461031357600080fd5b80633be1ced7116101155780633be1ced7146102145780633f4ba83a146102375780635c975abb1461023f5780636d7fbb6714610250578063715018a6146102705780637cde0fe21461027857600080fd5b8063011023901461015257806314067f8b1461017a57806315027bda146101cc578063181dfdff146101ec5780632972b0f014610201575b600080fd5b610165610160366004611b9e565b6103c7565b60405190151581526020015b60405180910390f35b6101b7610188366004611b9e565b6000918252602080805260408084206001600160a01b0393909316845291905290206002015463ffffffff1690565b60405163ffffffff9091168152602001610171565b6101df6101da366004611ce8565b6103de565b6040516101719190611e3f565b6101ff6101fa366004611f20565b6104cf565b005b61016561020f366004611f93565b610598565b610227610222366004611b9e565b6105ab565b6040516101719493929190611fbd565b6101ff6106c1565b60005462010000900460ff16610165565b61026361025e366004611b9e565b6106fd565b6040516101719190611ffa565b6101ff6107b5565b6101ff61028636600461200d565b6107f1565b6101ff610833565b6102a66102a1366004611b9e565b61086d565b6040516101719190612040565b6102c66102c1366004611b9e565b61089a565b604051908152602001610171565b600054630100000090046001600160a01b03165b6040516001600160a01b039091168152602001610171565b6101ff61030e366004612053565b6108a6565b6101ff6103213660046120a0565b61093b565b6101ff6103343660046120d9565b610979565b6102e8610347366004611b9e565b6000918252602080805260408084206001600160a01b039384168552909152909120541690565b61038161037c366004611ce8565b610a3c565b60405161017191906120f4565b6101ff61039c36600461214c565b610afc565b6101ff6103af3660046122d3565b610e41565b6101ff6103c23660046120d9565b611299565b60006103d3838361134b565b151590505b92915050565b6060600083516001600160401b038111156103fb576103fb611bca565b60405190808252806020026020018201604052801561044c57816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816104195790505b50905060005b84518110156104c75761049785828151811061047057610470612347565b602002602001015185838151811061048a5761048a612347565b6020026020010151611374565b8282815181106104a9576104a9612347565b602002602001018190525080806104bf90612373565b915050610452565b509392505050565b6000546001600160a01b03630100000090910416331461050a5760405162461bcd60e51b81526004016105019061238c565b60405180910390fd5b60005b815181101561059257610580848284848151811061052d5761052d612347565b602002602001015161053f91906123c1565b85848151811061055157610551612347565b60200260200101516000015186858151811061056f5761056f612347565b602002602001015160200151611483565b8061058a81612373565b91505061050d565b50505050565b60006105a48383611722565b9392505050565b6000828152602080805260408083206001600160a01b038086168552908352818420825160808101845281549092168252600181015493820193909352600283015463ffffffff1691810191909152600382018054849384936060938593919291838601919061061a906123d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610646906123d8565b80156106935780601f1061066857610100808354040283529160200191610693565b820191906000526020600020905b81548152906001019060200180831161067657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000546001600160a01b0363010000009091041633146106f35760405162461bcd60e51b81526004016105019061238c565b6106fb611744565b565b6000828152602080805260408083206001600160a01b0385168452909152902060030180546060919061072f906123d8565b80601f016020809104026020016040519081016040528092919081815260200182805461075b906123d8565b80156107a85780601f1061077d576101008083540402835291602001916107a8565b820191906000526020600020905b81548152906001019060200180831161078b57829003601f168201915b5050505050905092915050565b6000546001600160a01b0363010000009091041633146107e75760405162461bcd60e51b81526004016105019061238c565b6106fb60006117df565b6000546001600160a01b0363010000009091041633146108235760405162461bcd60e51b81526004016105019061238c565b61082e83838361183c565b505050565b6000546001600160a01b0363010000009091041633146108655760405162461bcd60e51b81526004016105019061238c565b6106fb6118ce565b60408051608081018252600080825260208201819052918101919091526060808201526105a48383611374565b60006105a4838361134b565b6000546001600160a01b0363010000009091041633146108d85760405162461bcd60e51b81526004016105019061238c565b60005b815181101561082e57610929838383815181106108fa576108fa612347565b60200260200101516000015184848151811061091857610918612347565b60200260200101516020015161183c565b8061093381612373565b9150506108db565b6000546001600160a01b03630100000090910416331461096d5760405162461bcd60e51b81526004016105019061238c565b61059284848484611483565b600054610100900460ff166109945760005460ff1615610998565b303b155b6109fb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610501565b600054610100900460ff16158015610a1d576000805461ffff19166101011790555b610a26826117df565b8015610a38576000805461ff00191690555b5050565b6060600083516001600160401b03811115610a5957610a59611bca565b604051908082528060200260200182016040528015610a82578160200160208202803683370190505b50905060005b84518110156104c757610acd858281518110610aa657610aa6612347565b6020026020010151858381518110610ac057610ac0612347565b602002602001015161134b565b828281518110610adf57610adf612347565b602090810291909101015280610af481612373565b915050610a88565b60005462010000900460ff1615610b255760405162461bcd60e51b815260040161050190612412565b3360005b825181101561082e57600060206000858481518110610b4a57610b4a612347565b60200260200101516000015181526020019081526020016000206000858481518110610b7857610b78612347565b6020026020010151602001516001600160a01b03166001600160a01b03168152602001908152602001600020600101549050610bd183858481518110610bc057610bc0612347565b602002602001015160000151611722565b610c1e5782848381518110610be857610be8612347565b60209081029190910101515160405163c522f21160e01b81526001600160a01b0390921660048301526024820152604401610501565b60206000858481518110610c3457610c34612347565b60200260200101516000015181526020019081526020016000206000858481518110610c6257610c62612347565b6020908102919091018101518101516001600160a01b03168252810191909152604001600090812080546001600160a01b03191681556001810182905560028101805463ffffffff1916905590610cbc6003830182611aaf565b5050610d05848381518110610cd357610cd3612347565b602002602001015160000151858481518110610cf157610cf1612347565b602002602001015160200151836000611930565b7f01cba57fa881d11e8be5640b6abefb9709f2dd45f776051b2cf5cb8ea23fa56b6040518060c00160405280868581518110610d4357610d43612347565b6020026020010151600001518152602001868581518110610d6657610d66612347565b6020026020010151602001516001600160a01b03168152602001868581518110610d9257610d92612347565b6020026020010151604001516001600160a01b03168152602001868581518110610dbe57610dbe612347565b6020026020010151606001518152602001868581518110610de157610de1612347565b60200260200101516080015163ffffffff168152602001868581518110610e0a57610e0a612347565b602002602001015160a00151815250604051610e26919061243c565b60405180910390a15080610e3981612373565b915050610b29565b60005462010000900460ff1615610e6a5760405162461bcd60e51b815260040161050190612412565b3360005b8281101561059257610ea482858584818110610e8c57610e8c612347565b9050602002810190610e9e919061249d565b35611722565b610ef85781848483818110610ebb57610ebb612347565b9050602002810190610ecd919061249d565b60405163c522f21160e01b81526001600160a01b039092166004830152356024820152604401610501565b600060206000868685818110610f1057610f10612347565b9050602002810190610f22919061249d565b6000013581526020019081526020016000206000868685818110610f4857610f48612347565b9050602002810190610f5a919061249d565b610f6b9060408101906020016120d9565b6001600160a01b03166001600160a01b031681526020019081526020016000206001015490506040518060800160405280868685818110610fae57610fae612347565b9050602002810190610fc0919061249d565b610fd19060608101906040016120d9565b6001600160a01b03168152602001868685818110610ff157610ff1612347565b9050602002810190611003919061249d565b60600135815260200186868581811061101e5761101e612347565b9050602002810190611030919061249d565b6110419060a08101906080016124bd565b63ffffffff16815260200186868581811061105e5761105e612347565b9050602002810190611070919061249d565b61107e9060a08101906124d8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452506020925088905087868181106110cb576110cb612347565b90506020028101906110dd919061249d565b600001358152602001908152602001600020600087878681811061110357611103612347565b9050602002810190611115919061249d565b6111269060408101906020016120d9565b6001600160a01b0390811682526020808301939093526040918201600020845181546001600160a01b03191692169190911781558383015160018201559083015160028201805463ffffffff191663ffffffff90921691909117905560608301518051919261119d92600385019290910190611ae9565b5090505061122c8585848181106111b6576111b6612347565b90506020028101906111c8919061249d565b358686858181106111db576111db612347565b90506020028101906111ed919061249d565b6111fe9060408101906020016120d9565b8388888781811061121157611211612347565b9050602002810190611223919061249d565b60600135611930565b7f8c20c3acb6b5208b7affea2fd90dabc8d47e77cee9766c855ce42730505cb20585858481811061125f5761125f612347565b9050602002810190611271919061249d565b60405161127e919061254e565b60405180910390a1508061129181612373565b915050610e6e565b6000546001600160a01b0363010000009091041633146112cb5760405162461bcd60e51b81526004016105019061238c565b6001600160a01b0381166113305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610501565b611339816117df565b50565b6001600160a01b03163b151590565b6000918252602080805260408084206001600160a01b0393909316845291905290206001015490565b60408051608081018252600080825260208201819052918101919091526060808201526000838152602080805260408083206001600160a01b03808716855290835292819020815160808101835281549094168452600181015492840192909252600282015463ffffffff16908301526003810180546060840191906113f9906123d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611425906123d8565b80156114725780601f1061144757610100808354040283529160200191611472565b820191906000526020600020905b81548152906001019060200180831161145557829003601f168201915b505050505081525050905092915050565b6000546001600160a01b0363010000009091041633146114b55760405162461bcd60e51b81526004016105019061238c565b6001600160a01b0384166000908152601060205260409020548310611517576001600160a01b038416600081815260106020526040908190205490516345e388eb60e01b81526004810192909252602482015260448101849052606401610501565b6001600160a01b038416600090815260106020526040812080548590811061154157611541612347565b600091825260208083206002909202909101546001600160a01b03881683526010909152604082208054919350908690811061157f5761157f612347565b906000526020600020906002020160010154905081841415806115a25750808314155b156115ee57604051637a4dd76560e01b81526001600160a01b03871660048201526024810186905260448101839052606481018290526084810185905260a4810184905260c401610501565b6001600160a01b03861660009081526010602052604090208054611614906001906123c1565b8154811061162457611624612347565b906000526020600020906002020160106000886001600160a01b03166001600160a01b03168152602001908152602001600020868154811061166857611668612347565b60009182526020808320845460029093020191825560019384015493909101929092556001600160a01b03881681526010909152604090208054806116af576116af61260b565b6000828152602080822060026000199490940193840201828155600101919091559155604080516001600160a01b038916815291820186905281018490527f33cff58e54c3a8acae85cad63487b5dcf617521e33bb03f071299f374c29de1f9060600160405180910390a1505050505050565b6001600160a01b03821660009081526010602052604081206105a49083611a21565b60005462010000900460ff166117935760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610501565b6000805462ff0000191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600080546001600160a01b0383811663010000008181026301000000600160b81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b60408051808201825283815260208082018481526001600160a01b03871660008181526010845285812080546001808201835591835291859020865160029093020191825592519201919091558351908152908101859052918201839052907fe7d6ac0b740347f7f96a97e6a9dc0f20f4f11eca65495315adc009a55b6762f89060600160405180910390a150505050565b60005462010000900460ff16156118f75760405162461bcd60e51b815260040161050190612412565b6000805462ff00001916620100001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117c23390565b818111306000826119415785611944565b60005b9050600083611954576000611956565b865b905060008461196e5761196986886123c1565b611978565b61197887876123c1565b604051633885984b60e11b81526001600160a01b03868116600483015285811660248301528481166044830152606482018c9052608482018390529192507f000000000000000000000000f12494e3545d49616d9dfb78e5907e9078618a349091169063710b30969060a401600060405180830381600087803b1580156119fe57600080fd5b505af1158015611a12573d6000803e3d6000fd5b50505050505050505050505050565b6000805b8354811015611aa557838181548110611a4057611a40612347565b9060005260206000209060020201600001548310158015611a845750838181548110611a6e57611a6e612347565b9060005260206000209060020201600101548311155b15611a935760019150506103d8565b80611a9d81612373565b915050611a25565b5060009392505050565b508054611abb906123d8565b6000825580601f10611acb575050565b601f0160209004906000526020600020908101906113399190611b6d565b828054611af5906123d8565b90600052602060002090601f016020900481019282611b175760008555611b5d565b82601f10611b3057805160ff1916838001178555611b5d565b82800160010185558215611b5d579182015b82811115611b5d578251825591602001919060010190611b42565b50611b69929150611b6d565b5090565b5b80821115611b695760008155600101611b6e565b80356001600160a01b0381168114611b9957600080fd5b919050565b60008060408385031215611bb157600080fd5b82359150611bc160208401611b82565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611c0257611c02611bca565b60405290565b60405160c081016001600160401b0381118282101715611c0257611c02611bca565b604051601f8201601f191681016001600160401b0381118282101715611c5257611c52611bca565b604052919050565b60006001600160401b03821115611c7357611c73611bca565b5060051b60200190565b600082601f830112611c8e57600080fd5b81356020611ca3611c9e83611c5a565b611c2a565b82815260059290921b84018101918181019086841115611cc257600080fd5b8286015b84811015611cdd5780358352918301918301611cc6565b509695505050505050565b60008060408385031215611cfb57600080fd5b82356001600160401b0380821115611d1257600080fd5b611d1e86838701611c7d565b9350602091508185013581811115611d3557600080fd5b85019050601f81018613611d4857600080fd5b8035611d56611c9e82611c5a565b81815260059190911b82018301908381019088831115611d7557600080fd5b928401925b82841015611d9a57611d8b84611b82565b82529284019290840190611d7a565b80955050505050509250929050565b6000815180845260005b81811015611dcf57602081850181015186830182015201611db3565b81811115611de1576000602083870101525b50601f01601f19169290920160200192915050565b60018060a01b0381511682526020810151602083015263ffffffff60408201511660408301526000606082015160806060850152611e376080850182611da9565b949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611e9457603f19888603018452611e82858351611df6565b94509285019290850190600101611e66565b5092979650505050505050565b600082601f830112611eb257600080fd5b81356020611ec2611c9e83611c5a565b82815260069290921b84018101918181019086841115611ee157600080fd5b8286015b84811015611cdd5760408189031215611efe5760008081fd5b611f06611be0565b813581528482013585820152835291830191604001611ee5565b600080600060608486031215611f3557600080fd5b611f3e84611b82565b925060208401356001600160401b0380821115611f5a57600080fd5b611f6687838801611ea1565b93506040860135915080821115611f7c57600080fd5b50611f8986828701611c7d565b9150509250925092565b60008060408385031215611fa657600080fd5b611faf83611b82565b946020939093013593505050565b60018060a01b038516815283602082015263ffffffff83166040820152608060608201526000611ff06080830184611da9565b9695505050505050565b6020815260006105a46020830184611da9565b60008060006060848603121561202257600080fd5b61202b84611b82565b95602085013595506040909401359392505050565b6020815260006105a46020830184611df6565b6000806040838503121561206657600080fd5b61206f83611b82565b915060208301356001600160401b0381111561208a57600080fd5b61209685828601611ea1565b9150509250929050565b600080600080608085870312156120b657600080fd5b6120bf85611b82565b966020860135965060408601359560600135945092505050565b6000602082840312156120eb57600080fd5b6105a482611b82565b6020808252825182820181905260009190848201906040850190845b8181101561212c57835183529284019291840191600101612110565b50909695505050505050565b803563ffffffff81168114611b9957600080fd5b6000602080838503121561215f57600080fd5b82356001600160401b038082111561217657600080fd5b818501915085601f83011261218a57600080fd5b8135612198611c9e82611c5a565b81815260059190911b830184019084810190888311156121b757600080fd5b8585015b838110156122c6578035858111156121d35760008081fd5b860160c0601f19828d0381018213156121ec5760008081fd5b6121f4611c08565b8a84013581526040612207818601611b82565b8c8301526060612218818701611b82565b828401526080808701358285015260a09150612235828801612138565b9084015293850135938a85111561224c5760008081fd5b84860195508f603f87011261226357600094508485fd5b8c86013594508a85111561227957612279611bca565b6122898d85601f88011601611c2a565b93508484528f828688010111156122a05760008081fd5b848287018e86013760009484018d019490945250918201528452509186019186016121bb565b5098975050505050505050565b600080602083850312156122e657600080fd5b82356001600160401b03808211156122fd57600080fd5b818501915085601f83011261231157600080fd5b81358181111561232057600080fd5b8660208260051b850101111561233557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016123855761238561235d565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000828210156123d3576123d361235d565b500390565b600181811c908216806123ec57607f821691505b60208210810361240c57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208152815160208201526000602083015160018060a01b03808216604085015280604086015116606085015250506060830151608083015263ffffffff60808401511660a083015260a083015160c080840152611e3760e0840182611da9565b6000823560be198336030181126124b357600080fd5b9190910192915050565b6000602082840312156124cf57600080fd5b6105a482612138565b6000808335601e198436030181126124ef57600080fd5b8301803591506001600160401b0382111561250957600080fd5b60200191503681900382131561251e57600080fd5b9250929050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815281356020820152600061256760208401611b82565b60018060a01b0380821660408501528061258360408701611b82565b16606085015250506060830135608083015263ffffffff6125a660808501612138565b1660a083015260a0830135601e198436030181126125c357600080fd5b83016020810190356001600160401b038111156125df57600080fd5b8036038213156125ee57600080fd5b60c08085015261260260e085018284612525565b95945050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220c903c76a32e6925df15285171ac55d0624e9da3ca4368c9b9fa0c5e0482dd28864736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009fbe1230aa270f55870dd0c631ef3f4cc54a1dda000000000000000000000000f12494e3545d49616d9dfb78e5907e9078618a34
-----Decoded View---------------
Arg [0] : owner (address): 0x9FBE1230aa270F55870DD0c631ef3f4cC54A1Dda
Arg [1] : badgesAddress (address): 0xF12494e3545D49616D9dFb78E5907E9078618a34
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000009fbe1230aa270f55870dd0c631ef3f4cc54a1dda
Arg [1] : 000000000000000000000000f12494e3545d49616d9dfb78e5907e9078618a34
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.