Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
GitcoinPassportDecoder
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL pragma solidity ^0.8.9; import {Initializable, OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {Attestation, IEAS} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol"; import {IGitcoinResolver} from "./IGitcoinResolver.sol"; import {Credential, IGitcoinPassportDecoder} from "./IGitcoinPassportDecoder.sol"; /** * @title GitcoinPassportDecoder * @notice This contract is used to create the bit map of stamp providers onchain, which will allow us to score Passports fully onchain */ contract GitcoinPassportDecoder is IGitcoinPassportDecoder, Initializable, UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable { // The instance of the EAS contract. IEAS public eas; // Mapping of the current version to provider arrays mapping(uint32 => string[]) public providerVersions; // Mapping of previously stored providers mapping(uint32 => mapping(string => uint8)) public reversedMappingVersions; // Current version number uint32 public currentVersion; // Instance of the GitcoinResolver contract IGitcoinResolver public gitcoinResolver; // Passport attestation schema UID bytes32 public passportSchemaUID; // Score attestation schema UID bytes32 public scoreSchemaUID; // Maximum score age in seconds uint64 public maxScoreAge; // Minimum score uint256 public threshold; // Score attestation schema UID bytes32 public scoreV2SchemaUID; /// A provider with the same name already exists /// @param provider the name of the duplicate provider error ProviderAlreadyExists(string provider); /// An empty provider string was passed error EmptyProvider(); /// Zero value was passed error ZeroValue(); /// An attestation for the specified ETH address does not exist within the GitcoinResolver error AttestationNotFound(); /// An attestation was found but it is expired /// @param expirationTime the expiration time of the attestation error AttestationExpired(uint64 expirationTime); /// A threshold of zero was passed error ZeroThreshold(); /// A max score age of zero was passed error ZeroMaxScoreAge(); /// Score does not meet the threshold error ScoreDoesNotMeetThreshold(uint256 score); // Events event EASSet(address easAddress); event ResolverSet(address resolverAddress); event SchemaSet(bytes32 schemaUID); event ProvidersAdded(string[] providers); event NewVersionCreated(); event MaxScoreAgeSet(uint256 maxScoreAge); event ThresholdSet(uint256 threshold); function initialize() public initializer { __Ownable_init(); __Pausable_init(); _initCurrentVersion(new string[](0)); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function _authorizeUpgrade(address) internal override onlyOwner {} /** * @dev Gets providers by version. */ function getProviders(uint32 version) public view returns (string[] memory) { return providerVersions[version]; } /** * @dev Sets the address of the EAS contract. * @param _easContractAddress The address of the EAS contract. */ function setEASAddress(address _easContractAddress) external onlyOwner { if (_easContractAddress == address(0)) { revert ZeroValue(); } eas = IEAS(_easContractAddress); emit EASSet(_easContractAddress); } /** * @dev Sets the GitcoinResolver contract. * @param _gitcoinResolver The address of the GitcoinResolver contract. */ function setGitcoinResolver(address _gitcoinResolver) external onlyOwner { if (_gitcoinResolver == address(0)) { revert ZeroValue(); } gitcoinResolver = IGitcoinResolver(_gitcoinResolver); emit ResolverSet(_gitcoinResolver); } /** * @dev Sets the schemaUID for the Passport Attestation. * @param _schemaUID The UID of the schema used to make the user's passport attestation */ function setPassportSchemaUID(bytes32 _schemaUID) public onlyOwner { if (_schemaUID == bytes32(0)) { revert ZeroValue(); } passportSchemaUID = _schemaUID; emit SchemaSet(_schemaUID); } /** * @dev Sets the schemaUID for the Score Attestation. * @param _schemaUID The UID of the schema used to make the user's score attestation */ function setScoreSchemaUID(bytes32 _schemaUID) public onlyOwner { if (_schemaUID == bytes32(0)) { revert ZeroValue(); } scoreSchemaUID = _schemaUID; emit SchemaSet(_schemaUID); } /** * @dev Sets the schemaUID for the Score Attestation. * @param _schemaUID The UID of the schema used to make the user's score attestation */ function setScoreV2SchemaUID(bytes32 _schemaUID) public onlyOwner { if (_schemaUID == bytes32(0)) { revert ZeroValue(); } scoreV2SchemaUID = _schemaUID; emit SchemaSet(_schemaUID); } /** * @dev Sets the maximum allowed age of the score * @param _maxScoreAge Max age of the score in seconds */ function setMaxScoreAge(uint64 _maxScoreAge) public onlyOwner { if (_maxScoreAge == 0) { revert ZeroMaxScoreAge(); } maxScoreAge = _maxScoreAge; emit MaxScoreAgeSet(maxScoreAge); } /** * @dev Sets the threshold for the minimum score * @param _threshold Minimum score allowed, as a 4 digit number */ function setThreshold(uint256 _threshold) public onlyOwner { if (_threshold == 0) { revert ZeroThreshold(); } threshold = _threshold; emit ThresholdSet(threshold); } /** * @dev Adds a new provider to the end of the providerVersions mapping * @param providers provider name */ function addProviders(string[] memory providers) external onlyOwner { for (uint256 i = 0; i < providers.length; ) { if (bytes(providers[i]).length == 0) { revert EmptyProvider(); } if (reversedMappingVersions[currentVersion][providers[i]] == 1) { revert ProviderAlreadyExists(providers[i]); } providerVersions[currentVersion].push(providers[i]); reversedMappingVersions[currentVersion][providers[i]] = 1; unchecked { ++i; } } emit ProvidersAdded(providers); } /** * @dev Creates a new provider. * @param providers Array of provider names */ function _initCurrentVersion(string[] memory providers) internal { for (uint256 i = 0; i < providers.length; ) { if (bytes(providers[i]).length == 0) { revert EmptyProvider(); } unchecked { ++i; } } providerVersions[currentVersion] = providers; } /** * @dev Creates a new provider. * @param providers Array of provider names */ function createNewVersion(string[] memory providers) external onlyOwner { currentVersion++; _initCurrentVersion(providers); emit NewVersionCreated(); } /** * Return an attestation for a given UID * @param attestationUID The UID of the attestation */ function getAttestation( bytes32 attestationUID ) public view returns (Attestation memory) { Attestation memory attestation = eas.getAttestation(attestationUID); return attestation; } function _getPassportFromScoreV2( bytes32 attestationUID ) internal view returns (Credential[] memory) { // Get the attestation from the user's attestation UID Attestation memory attestation = getAttestation(attestationUID); // Check for expiration time if ( attestation.expirationTime > 0 && attestation.expirationTime <= block.timestamp ) { revert AttestationExpired(attestation.expirationTime); } // Decode the attestion output (, , , , , IGitcoinResolver.Stamp[] memory stamps) = abi.decode( attestation.data, (bool, uint8, uint128, uint32, uint32, IGitcoinResolver.Stamp[]) ); Credential[] memory credentials = new Credential[](stamps.length); for (uint256 i = 0; i < stamps.length; ) { credentials[i].provider = stamps[i].provider; credentials[i].hash = bytes32(0); credentials[i].time = attestation.time; credentials[i].expirationTime = attestation.expirationTime; unchecked { ++i; } } return credentials; } /** * @dev Retrieves the user's Passport attestation via the GitcoinResolver and IEAS and decodes the bits in the provider map to output a readable Passport * @param user User's address */ function getPassport( address user ) external view returns (Credential[] memory) { bytes32 scoreV2AttestationUID = gitcoinResolver.getUserAttestation( user, scoreV2SchemaUID ); if (scoreV2AttestationUID != 0) { return _getPassportFromScoreV2(scoreV2AttestationUID); } // Get the attestation UID from the user's attestations bytes32 attestationUID = gitcoinResolver.getUserAttestation( user, passportSchemaUID ); // Check if the attestation UID exists within the GitcoinResolver. When an attestation is revoked that attestation UID is set to 0. if (attestationUID == 0) { revert AttestationNotFound(); } // Get the attestation from the user's attestation UID Attestation memory attestation = getAttestation(attestationUID); // Check for expiration time if ( attestation.expirationTime > 0 && attestation.expirationTime <= block.timestamp ) { revert AttestationExpired(attestation.expirationTime); } // Set up the variables to assign the attestion data output to uint256[] memory providers; bytes32[] memory hashes; uint64[] memory issuanceDates; uint64[] memory expirationDates; uint16 providerMapVersion; // Decode the attestion output ( providers, hashes, issuanceDates, expirationDates, providerMapVersion ) = abi.decode( attestation.data, (uint256[], bytes32[], uint64[], uint64[], uint16) ); // Set up the variables to record the bit and the index of the credential hash uint256 bit; uint256 hashIndex = 0; // Set the list of providers to the provider map version string[] memory mappedProviders = providerVersions[providerMapVersion]; uint256 hashLength = uint256(hashes.length); uint256 providersBucketsLength = uint256(providers.length); uint256 mappedProvidersLength = uint256(mappedProviders.length); // Check to make sure that the lengths of the hashes, issuanceDates, and expirationDates match, otherwise end the function call assert( hashLength == issuanceDates.length && hashLength == expirationDates.length ); // Set the in-memory passport array to be returned to equal the length of the hashes array Credential[] memory passportMemoryArray = new Credential[](hashLength); // Now we iterate over the providers array and check each bit that is set // If a bit is set // we set the hash, issuanceDate, expirationDate, and provider to a Credential struct // then we push that struct to the passport storage array and populate the passportMemoryArray for (uint256 i = 0; i < providersBucketsLength; ) { bit = 1; uint256 provider = uint256(providers[i]); for (uint256 j = 0; j < 256; ) { // Check to make sure that the hashIndex is less than the length of the expirationDates array, and if not, exit the loop if (hashIndex >= hashLength) { break; } uint256 mappedProvidersIndex = i * 256 + j; if (mappedProvidersIndex > mappedProvidersLength) { break; } // Check that the provider bit is set // The provider bit is set --> set the provider, hash, issuance date, and expiration date to the struct if (provider & bit > 0) { Credential memory credential; // Set provider to the credential struct from the mappedProviders mapping credential.provider = mappedProviders[mappedProvidersIndex]; // Set the hash to the credential struct from the hashes array credential.hash = hashes[hashIndex]; // Set the issuanceDate of the credential struct to the item at the current index of the issuanceDates array credential.time = issuanceDates[hashIndex]; // Set the expirationDate of the credential struct to the item at the current index of the expirationDates array credential.expirationTime = expirationDates[hashIndex]; // Set the hashIndex with the finished credential struct passportMemoryArray[hashIndex] = credential; hashIndex += 1; } unchecked { bit <<= 1; ++j; } } unchecked { i += 256; } } // Return the memory passport array return passportMemoryArray; } /** * This function will check a cached score for expiration * * @param score The attestation to check for expiration */ function _checkExpiration( IGitcoinResolver.CachedScore memory score ) internal view { // Use score expiration if available uint64 expirationTime = score.expirationTime; if (expirationTime == 0) { // Otherwise, use maxScoreAge expirationTime = score.time + maxScoreAge; } if (block.timestamp >= expirationTime) { revert AttestationExpired(expirationTime); } } /** * @dev Retrieves the user's Score attestation via the GitcoinResolver and returns it as a 4 digit number * @param user The ETH address of the recipient */ function getScore(address user) public view returns (uint256) { IGitcoinResolver.CachedScore memory cachedScore = gitcoinResolver .getCachedScore(user); if (cachedScore.time == 0) { revert AttestationNotFound(); } _checkExpiration(cachedScore); // Return the score value return cachedScore.score; } /** * @dev Retrieves the user's Score attestation for a given community via the GitcoinResolver and returns it as a 4 digit number * @param user The ETH address of the recipient */ function getScore( uint32 communityId, address user ) public view returns (uint256) { IGitcoinResolver.CachedScore memory cachedScore = gitcoinResolver .getCachedScore(communityId, user); if (cachedScore.time == 0) { revert AttestationNotFound(); } _checkExpiration(cachedScore); // Return the score value return cachedScore.score; } /** * @dev Determines if a user is a human based on their score being above a certain threshold and valid within the max score age * @param user The ETH address of the recipient */ function isHuman(address user) public view returns (bool) { bytes32 scoreV2AttestationUID = gitcoinResolver.getUserAttestation( user, scoreV2SchemaUID ); if (scoreV2AttestationUID != 0) { Attestation memory attestation = getAttestation(scoreV2AttestationUID); if ( attestation.expirationTime > 0 && attestation.expirationTime <= block.timestamp ) { revert AttestationExpired(attestation.expirationTime); } // Decode the attestion output (bool passing_score, , , , , ) = abi.decode( attestation.data, (bool, uint8, uint128, uint32, uint32, IGitcoinResolver.Stamp[]) ); return passing_score; } uint256 score = getScore(user); return score >= threshold; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // A representation of an empty/uninitialized UID. bytes32 constant EMPTY_UID = 0; // A zero expiration represents an non-expiring attestation. uint64 constant NO_EXPIRATION_TIME = 0; error AccessDenied(); error DeadlineExpired(); error InvalidEAS(); error InvalidLength(); error InvalidSignature(); error NotFound(); /// @notice A struct representing ECDSA signature data. struct Signature { uint8 v; // The recovery ID. bytes32 r; // The x-coordinate of the nonce R. bytes32 s; // The signature data. } /// @notice A struct representing a single attestation. struct Attestation { bytes32 uid; // A unique identifier of the attestation. bytes32 schema; // The unique identifier of the schema. uint64 time; // The time when the attestation was created (Unix timestamp). uint64 expirationTime; // The time when the attestation expires (Unix timestamp). uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp). bytes32 refUID; // The UID of the related attestation. address recipient; // The recipient of the attestation. address attester; // The attester/sender of the attestation. bool revocable; // Whether the attestation is revocable. bytes data; // Custom attestation data. } /// @notice A helper function to work with unchecked iterators in loops. function uncheckedInc(uint256 i) pure returns (uint256 j) { unchecked { j = i + 1; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISchemaRegistry } from "./ISchemaRegistry.sol"; import { Attestation, Signature } from "./Common.sol"; /// @notice A struct representing the arguments of the attestation request. struct AttestationRequestData { address recipient; // The recipient of the attestation. uint64 expirationTime; // The time when the attestation expires (Unix timestamp). bool revocable; // Whether the attestation is revocable. bytes32 refUID; // The UID of the related attestation. bytes data; // Custom attestation data. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. } /// @notice A struct representing the full arguments of the attestation request. struct AttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData data; // The arguments of the attestation request. } /// @notice A struct representing the full arguments of the full delegated attestation request. struct DelegatedAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData data; // The arguments of the attestation request. Signature signature; // The ECDSA signature data. address attester; // The attesting account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the full arguments of the multi attestation request. struct MultiAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData[] data; // The arguments of the attestation request. } /// @notice A struct representing the full arguments of the delegated multi attestation request. struct MultiDelegatedAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData[] data; // The arguments of the attestation requests. Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces. address attester; // The attesting account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the arguments of the revocation request. struct RevocationRequestData { bytes32 uid; // The UID of the attestation to revoke. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. } /// @notice A struct representing the full arguments of the revocation request. struct RevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData data; // The arguments of the revocation request. } /// @notice A struct representing the arguments of the full delegated revocation request. struct DelegatedRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData data; // The arguments of the revocation request. Signature signature; // The ECDSA signature data. address revoker; // The revoking account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the full arguments of the multi revocation request. struct MultiRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData[] data; // The arguments of the revocation request. } /// @notice A struct representing the full arguments of the delegated multi revocation request. struct MultiDelegatedRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData[] data; // The arguments of the revocation requests. Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces. address revoker; // The revoking account. uint64 deadline; // The deadline of the signature/request. } /// @title IEAS /// @notice EAS - Ethereum Attestation Service interface. interface IEAS { /// @notice Emitted when an attestation has been made. /// @param recipient The recipient of the attestation. /// @param attester The attesting account. /// @param uid The UID the revoked attestation. /// @param schemaUID The UID of the schema. event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID); /// @notice Emitted when an attestation has been revoked. /// @param recipient The recipient of the attestation. /// @param attester The attesting account. /// @param schemaUID The UID of the schema. /// @param uid The UID the revoked attestation. event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID); /// @notice Emitted when a data has been timestamped. /// @param data The data. /// @param timestamp The timestamp. event Timestamped(bytes32 indexed data, uint64 indexed timestamp); /// @notice Emitted when a data has been revoked. /// @param revoker The address of the revoker. /// @param data The data. /// @param timestamp The timestamp. event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp); /// @notice Returns the address of the global schema registry. /// @return The address of the global schema registry. function getSchemaRegistry() external view returns (ISchemaRegistry); /// @notice Attests to a specific schema. /// @param request The arguments of the attestation request. /// @return The UID of the new attestation. /// /// Example: /// attest({ /// schema: "0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0", /// data: { /// recipient: "0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf", /// expirationTime: 0, /// revocable: true, /// refUID: "0x0000000000000000000000000000000000000000000000000000000000000000", /// data: "0xF00D", /// value: 0 /// } /// }) function attest(AttestationRequest calldata request) external payable returns (bytes32); /// @notice Attests to a specific schema via the provided ECDSA signature. /// @param delegatedRequest The arguments of the delegated attestation request. /// @return The UID of the new attestation. /// /// Example: /// attestByDelegation({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 0 /// }, /// signature: { /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e', /// deadline: 1673891048 /// }) function attestByDelegation( DelegatedAttestationRequest calldata delegatedRequest ) external payable returns (bytes32); /// @notice Attests to multiple schemas. /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct /// schema ids to benefit from the best batching optimization. /// @return The UIDs of the new attestations. /// /// Example: /// multiAttest([{ /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', /// data: [{ /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 1000 /// }, /// { /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 0, /// revocable: false, /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', /// data: '0x00', /// value: 0 /// }], /// }, /// { /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', /// data: [{ /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 0, /// revocable: true, /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', /// data: '0x12345678', /// value: 0 /// }, /// }]) function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory); /// @notice Attests to multiple schemas using via provided ECDSA signatures. /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be /// grouped by distinct schema ids to benefit from the best batching optimization. /// @return The UIDs of the new attestations. /// /// Example: /// multiAttestByDelegation([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 0 /// }, /// { /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 0, /// revocable: false, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x00', /// value: 0 /// }], /// signatures: [{ /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// { /// v: 28, /// r: '0x487s...67bb', /// s: '0x12ad...2366' /// }], /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4', /// deadline: 1673891048 /// }]) function multiAttestByDelegation( MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests ) external payable returns (bytes32[] memory); /// @notice Revokes an existing attestation to a specific schema. /// @param request The arguments of the revocation request. /// /// Example: /// revoke({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', /// value: 0 /// } /// }) function revoke(RevocationRequest calldata request) external payable; /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature. /// @param delegatedRequest The arguments of the delegated revocation request. /// /// Example: /// revokeByDelegation({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', /// value: 0 /// }, /// signature: { /// v: 27, /// r: '0xb593...7142', /// s: '0x0f5b...2cce' /// }, /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992', /// deadline: 1673891048 /// }) function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable; /// @notice Revokes existing attestations to multiple schemas. /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct /// schema ids to benefit from the best batching optimization. /// /// Example: /// multiRevoke([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', /// value: 1000 /// }, /// { /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', /// value: 0 /// }], /// }, /// { /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', /// data: [{ /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', /// value: 0 /// }, /// }]) function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable; /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures. /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests /// should be grouped by distinct schema ids to benefit from the best batching optimization. /// /// Example: /// multiRevokeByDelegation([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', /// value: 1000 /// }, /// { /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', /// value: 0 /// }], /// signatures: [{ /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// { /// v: 28, /// r: '0x487s...67bb', /// s: '0x12ad...2366' /// }], /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992', /// deadline: 1673891048 /// }]) function multiRevokeByDelegation( MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests ) external payable; /// @notice Timestamps the specified bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was timestamped with. function timestamp(bytes32 data) external returns (uint64); /// @notice Timestamps the specified multiple bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was timestamped with. function multiTimestamp(bytes32[] calldata data) external returns (uint64); /// @notice Revokes the specified bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was revoked with. function revokeOffchain(bytes32 data) external returns (uint64); /// @notice Revokes the specified multiple bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was revoked with. function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64); /// @notice Returns an existing attestation by UID. /// @param uid The UID of the attestation to retrieve. /// @return The attestation data members. function getAttestation(bytes32 uid) external view returns (Attestation memory); /// @notice Checks whether an attestation exists. /// @param uid The UID of the attestation to retrieve. /// @return Whether an attestation exists. function isAttestationValid(bytes32 uid) external view returns (bool); /// @notice Returns the timestamp that the specified data was timestamped with. /// @param data The data to query. /// @return The timestamp the data was timestamped with. function getTimestamp(bytes32 data) external view returns (uint64); /// @notice Returns the timestamp that the specified data was timestamped with. /// @param data The data to query. /// @return The timestamp the data was timestamped with. function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISchemaResolver } from "./resolver/ISchemaResolver.sol"; /// @notice A struct representing a record for a submitted schema. struct SchemaRecord { bytes32 uid; // The unique identifier of the schema. ISchemaResolver resolver; // Optional schema resolver. bool revocable; // Whether the schema allows revocations explicitly. string schema; // Custom specification of the schema (e.g., an ABI). } /// @title ISchemaRegistry /// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol. interface ISchemaRegistry { /// @notice Emitted when a new schema has been registered /// @param uid The schema UID. /// @param registerer The address of the account used to register the schema. /// @param schema The schema data. event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema); /// @notice Submits and reserves a new schema /// @param schema The schema data schema. /// @param resolver An optional schema resolver. /// @param revocable Whether the schema allows revocations explicitly. /// @return The UID of the new schema. function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32); /// @notice Returns an existing schema by UID /// @param uid The UID of the schema to retrieve. /// @return The schema data members. function getSchema(bytes32 uid) external view returns (SchemaRecord memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Attestation } from "../Common.sol"; /// @title ISchemaResolver /// @notice The interface of an optional schema resolver. interface ISchemaResolver { /// @notice Checks if the resolver can be sent ETH. /// @return Whether the resolver supports ETH transfers. function isPayable() external pure returns (bool); /// @notice Processes an attestation and verifies whether it's valid. /// @param attestation The new attestation. /// @return Whether the attestation is valid. function attest(Attestation calldata attestation) external payable returns (bool); /// @notice Processes multiple attestations and verifies whether they are valid. /// @param attestations The new attestations. /// @param values Explicit ETH amounts which were sent with each attestation. /// @return Whether all the attestations are valid. function multiAttest( Attestation[] calldata attestations, uint256[] calldata values ) external payable returns (bool); /// @notice Processes an attestation revocation and verifies if it can be revoked. /// @param attestation The existing attestation to be revoked. /// @return Whether the attestation can be revoked. function revoke(Attestation calldata attestation) external payable returns (bool); /// @notice Processes revocation of multiple attestation and verifies they can be revoked. /// @param attestations The existing attestations to be revoked. /// @param values Explicit ETH amounts which were sent with each revocation. /// @return Whether the attestations can be revoked. function multiRevoke( Attestation[] calldata attestations, uint256[] calldata values ) external payable returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * 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 prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 PausableUpgradeable is Initializable, ContextUpgradeable { /** * @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); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { 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()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-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.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: GPL pragma solidity ^0.8.9; /** * @dev A struct storing a passpor credential */ struct Credential { string provider; bytes32 hash; uint64 time; uint64 expirationTime; } /** * @title IGitcoinPassportDecoder * @notice Minimal interface for consuming GitcoinPassportDecoder data */ interface IGitcoinPassportDecoder { function getPassport( address user ) external returns (Credential[] memory); function getScore(address user) external view returns (uint256); function getScore(uint32 communityId, address user) external view returns (uint256); function isHuman(address user) external view returns (bool); }
// SPDX-License-Identifier: GPL pragma solidity ^0.8.9; /** * @title IGitcoinResolver * @notice Minimal interface for consuming GitcoinResolver data */ interface IGitcoinResolver { // Cached data structure // Stores a score in a 32 byte data structure for efficient access when reading struct CachedScore { uint32 score; // compacted uint value 4 decimal places uint64 time; // For checking the age of the stamp, without loading the attestation uint64 expirationTime; // This makes sense because we want to make sure the stamp is not expired, and also do not want to load the attestation } // @dev Stamp used in encoding of V2 scores struct Stamp { string provider; uint256 score; } /// @param user The ETH address of the recipient /// @param schema THE UID of the chema /// @return The attestation UID or 0x0 if not found /// @dev Returns the latest user attestation for a given schema /// @dev Not supported for community-specific attestations function getUserAttestation( address user, bytes32 schema ) external view returns (bytes32); /// @notice Get the cached score for a user in a the default community /// @param user The ETH address of the recipient /// @return The `CachedScore` for the given ETH address. /// @dev A non-zero value in the `issuanceDate` indicates that a valid score has been retreived. function getCachedScore( address user ) external view returns (CachedScore memory); /// @notice Get the cached score for a user in a specific community /// @param communityId The ID of the community /// @param user The ETH address of the recipient /// @return The `CachedScore` for the given ETH address. /// @dev A non-zero value in the `issuanceDate` indicates that a valid score has been retreived. function getCachedScore( uint32 communityId, address user ) external view returns (CachedScore memory); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint64","name":"expirationTime","type":"uint64"}],"name":"AttestationExpired","type":"error"},{"inputs":[],"name":"AttestationNotFound","type":"error"},{"inputs":[],"name":"EmptyProvider","type":"error"},{"inputs":[{"internalType":"string","name":"provider","type":"string"}],"name":"ProviderAlreadyExists","type":"error"},{"inputs":[{"internalType":"uint256","name":"score","type":"uint256"}],"name":"ScoreDoesNotMeetThreshold","type":"error"},{"inputs":[],"name":"ZeroMaxScoreAge","type":"error"},{"inputs":[],"name":"ZeroThreshold","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"easAddress","type":"address"}],"name":"EASSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxScoreAge","type":"uint256"}],"name":"MaxScoreAgeSet","type":"event"},{"anonymous":false,"inputs":[],"name":"NewVersionCreated","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":"string[]","name":"providers","type":"string[]"}],"name":"ProvidersAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"resolverAddress","type":"address"}],"name":"ResolverSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"schemaUID","type":"bytes32"}],"name":"SchemaSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"ThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"string[]","name":"providers","type":"string[]"}],"name":"addProviders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"providers","type":"string[]"}],"name":"createNewVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentVersion","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eas","outputs":[{"internalType":"contract IEAS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"attestationUID","type":"bytes32"}],"name":"getAttestation","outputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"bytes32","name":"schema","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"uint64","name":"revocationTime","type":"uint64"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Attestation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPassport","outputs":[{"components":[{"internalType":"string","name":"provider","type":"string"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"}],"internalType":"struct Credential[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"version","type":"uint32"}],"name":"getProviders","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"communityId","type":"uint32"},{"internalType":"address","name":"user","type":"address"}],"name":"getScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gitcoinResolver","outputs":[{"internalType":"contract IGitcoinResolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isHuman","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxScoreAge","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"passportSchemaUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"providerVersions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"string","name":"","type":"string"}],"name":"reversedMappingVersions","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scoreSchemaUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scoreV2SchemaUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_easContractAddress","type":"address"}],"name":"setEASAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gitcoinResolver","type":"address"}],"name":"setGitcoinResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_maxScoreAge","type":"uint64"}],"name":"setMaxScoreAge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_schemaUID","type":"bytes32"}],"name":"setPassportSchemaUID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_schemaUID","type":"bytes32"}],"name":"setScoreSchemaUID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_schemaUID","type":"bytes32"}],"name":"setScoreV2SchemaUID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"threshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff1681525034801561004357600080fd5b506080516153ad61007b600039600081816109af01528181610a3d01528181610f4c01528181610fda015261108a01526153ad6000f3fe6080604052600436106102045760003560e01c80638150864d11610118578063bb169f7f116100a0578063d47875d01161006f578063d47875d0146106fc578063daadd66214610739578063e4a5920914610776578063f2fde38b1461079f578063f72c436f146107c857610204565b8063bb169f7f14610654578063c82bfbb71461067d578063ceab3988146106a8578063d2ae372c146106d357610204565b806391c70059116100e757806391c700591461056f578063960bfe041461059a5780639d888e86146105c3578063a3112a64146105ee578063a46767b51461062b57610204565b80638150864d146104c55780638456cb59146104f057806386b69e8a146105075780638da5cb5b1461054457610204565b80634e62cf3f1161019b5780635c975abb1161016a5780635c975abb146104185780635e33ef5d146104435780636edbe6da1461046e578063715018a6146104975780638129fc1c146104ae57610204565b80634e62cf3f146103575780634f1ef2861461039457806352d1902d146103b057806357a5893c146103db57610204565b80633923d3ef116101d75780633923d3ef146102c35780633f4ba83a146102ec578063420b75891461030357806342cde4e81461032c57610204565b806315e94078146102095780631cd191e8146102345780632e314f65146102715780633659cfe61461029a575b600080fd5b34801561021557600080fd5b5061021e610805565b60405161022b919061302d565b60405180910390f35b34801561024057600080fd5b5061025b600480360381019061025691906130ce565b61080b565b604051610268919061319e565b60405180910390f35b34801561027d57600080fd5b506102986004803603810190610293919061321e565b6108c4565b005b3480156102a657600080fd5b506102c160048036038101906102bc919061321e565b6109ad565b005b3480156102cf57600080fd5b506102ea60048036038101906102e59190613466565b610b35565b005b3480156102f857600080fd5b50610301610bb6565b005b34801561030f57600080fd5b5061032a60048036038101906103259190613466565b610bc8565b005b34801561033857600080fd5b50610341610e4c565b60405161034e91906134be565b60405180910390f35b34801561036357600080fd5b5061037e600480360381019061037991906134d9565b610e52565b60405161038b9190613612565b60405180910390f35b6103ae60048036038101906103a991906136d5565b610f4a565b005b3480156103bc57600080fd5b506103c5611086565b6040516103d2919061302d565b60405180910390f35b3480156103e757600080fd5b5061040260048036038101906103fd919061321e565b61113f565b60405161040f9190613888565b60405180910390f35b34801561042457600080fd5b5061042d6116b9565b60405161043a91906138c5565b60405180910390f35b34801561044f57600080fd5b506104586116d0565b604051610465919061393f565b60405180910390f35b34801561047a57600080fd5b5061049560048036038101906104909190613986565b6116f6565b005b3480156104a357600080fd5b506104ac61177b565b005b3480156104ba57600080fd5b506104c361178f565b005b3480156104d157600080fd5b506104da61192c565b6040516104e791906139d4565b60405180910390f35b3480156104fc57600080fd5b50610505611952565b005b34801561051357600080fd5b5061052e600480360381019061052991906139ef565b611964565b60405161053b9190613a67565b60405180910390f35b34801561055057600080fd5b506105596119a9565b6040516105669190613a91565b60405180910390f35b34801561057b57600080fd5b506105846119d3565b604051610591919061302d565b60405180910390f35b3480156105a657600080fd5b506105c160048036038101906105bc9190613aac565b6119d9565b005b3480156105cf57600080fd5b506105d8611a5e565b6040516105e59190613ae8565b60405180910390f35b3480156105fa57600080fd5b5061061560048036038101906106109190613986565b611a74565b6040516106229190613c50565b60405180910390f35b34801561063757600080fd5b50610652600480360381019061064d9190613986565b611b2a565b005b34801561066057600080fd5b5061067b60048036038101906106769190613986565b611baf565b005b34801561068957600080fd5b50610692611c34565b60405161069f9190613c81565b60405180910390f35b3480156106b457600080fd5b506106bd611c4e565b6040516106ca919061302d565b60405180910390f35b3480156106df57600080fd5b506106fa60048036038101906106f5919061321e565b611c54565b005b34801561070857600080fd5b50610723600480360381019061071e919061321e565b611d3d565b60405161073091906134be565b60405180910390f35b34801561074557600080fd5b50610760600480360381019061075b9190613c9c565b611e42565b60405161076d91906134be565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613d08565b611f4a565b005b3480156107ab57600080fd5b506107c660048036038101906107c1919061321e565b61200f565b005b3480156107d457600080fd5b506107ef60048036038101906107ea919061321e565b612092565b6040516107fc91906138c5565b60405180910390f35b609f5481565b6098602052816000526040600020818154811061082757600080fd5b9060005260206000200160009150915050805461084390613d64565b80601f016020809104026020016040519081016040528092919081815260200182805461086f90613d64565b80156108bc5780601f10610891576101008083540402835291602001916108bc565b820191906000526020600020905b81548152906001019060200180831161089f57829003601f168201915b505050505081565b6108cc61220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610932576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609a60046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f14dc79d338b451b8b7b20e3191752ac97cbc8b011ff3b921597b83b1222896ae816040516109a29190613a91565b60405180910390a150565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613e07565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610a7a612288565b73ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790613e99565b60405180910390fd5b610ad9816122df565b610b3281600067ffffffffffffffff811115610af857610af7613250565b5b6040519080825280601f01601f191660200182016040528015610b2a5781602001600182028036833780820191505090505b5060006122ea565b50565b610b3d61220a565b609a600081819054906101000a900463ffffffff1680929190610b5f90613ee8565b91906101000a81548163ffffffff021916908363ffffffff16021790555050610b8781612458565b7f4e210ed25abf187b8a2f6c516deef88d958c75e285b05928d7db0f8a673ce25f60405160405180910390a150565b610bbe61220a565b610bc661250e565b565b610bd061220a565b60005b8151811015610e11576000828281518110610bf157610bf0613f14565b5b60200260200101515103610c31576040517f88998c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160996000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020838381518110610c7757610c76613f14565b5b6020026020010151604051610c8c9190613f7f565b908152602001604051809103902060009054906101000a900460ff1660ff1603610d0757818181518110610cc357610cc2613f14565b5b60200260200101516040517fee118ba6000000000000000000000000000000000000000000000000000000008152600401610cfe919061319e565b60405180910390fd5b60986000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020828281518110610d4b57610d4a613f14565b5b6020026020010151908060018154018082558091505060019003906000526020600020016000909190919091509081610d849190614138565b50600160996000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020838381518110610dcb57610dca613f14565b5b6020026020010151604051610de09190613f7f565b908152602001604051809103902060006101000a81548160ff021916908360ff160217905550806001019050610bd3565b507fec76e5d73810a27d70d44fe10dd9040c9c446187c33df2ae02ceb4b07cfa7eb781604051610e419190613612565b60405180910390a150565b609e5481565b6060609860008363ffffffff1663ffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f3f578382906000526020600020018054610eb290613d64565b80601f0160208091040260200160405190810160405280929190818152602001828054610ede90613d64565b8015610f2b5780601f10610f0057610100808354040283529160200191610f2b565b820191906000526020600020905b815481529060010190602001808311610f0e57829003601f168201915b505050505081526020019060010190610e93565b505050509050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf90613e07565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611017612288565b73ffffffffffffffffffffffffffffffffffffffff161461106d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106490613e99565b60405180910390fd5b611076826122df565b611082828260016122ea565b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611116576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110d9061427c565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905090565b60606000609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5684609f546040518363ffffffff1660e01b81526004016111a292919061429c565b602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e391906142da565b90506000801b8114611200576111f881612571565b9150506116b4565b6000609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5685609b546040518363ffffffff1660e01b815260040161126192919061429c565b602060405180830381865afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a291906142da565b90506000801b81036112e0576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006112eb82611a74565b90506000816060015167ffffffffffffffff16118015611319575042816060015167ffffffffffffffff1611155b1561135f5780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016113569190613c81565b60405180910390fd5b606080606080600085610120015180602001905181019061138091906145b4565b8095508196508297508398508499505050505050600080600090506000609860008561ffff1663ffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156114865783829060005260206000200180546113f990613d64565b80601f016020809104026020016040519081016040528092919081815260200182805461142590613d64565b80156114725780601f1061144757610100808354040283529160200191611472565b820191906000526020600020905b81548152906001019060200180831161145557829003601f168201915b5050505050815260200190600101906113da565b5050505090506000875190506000895190506000835190508851831480156114ae5750875183145b6114bb576114ba61469f565b5b60008367ffffffffffffffff8111156114d7576114d6613250565b5b60405190808252806020026020018201604052801561151057816020015b6114fd612e53565b8152602001906001900390816114f55790505b50905060005b838110156116a0576001975060008d828151811061153757611536613f14565b5b6020026020010151905060005b6101008110156116925786891015611692576000816101008561156791906146ce565b6115719190614710565b9050858111156115815750611692565b60008b8416111561167f57611594612e53565b8982815181106115a7576115a6613f14565b5b602002602001015181600001819052508f8b815181106115ca576115c9613f14565b5b60200260200101518160200181815250508e8b815181106115ee576115ed613f14565b5b6020026020010151816040019067ffffffffffffffff16908167ffffffffffffffff16815250508d8b8151811061162857611627613f14565b5b6020026020010151816060019067ffffffffffffffff16908167ffffffffffffffff168152505080868c8151811061166357611662613f14565b5b602002602001018190525060018b61167b9190614710565b9a50505b60018b901b9a5081600101915050611544565b506101008201915050611516565b50809f505050505050505050505050505050505b919050565b6000606560009054906101000a900460ff16905090565b609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6116fe61220a565b6000801b810361173a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609f819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611770919061302d565b60405180910390a150565b61178361220a565b61178d6000612774565b565b60008060019054906101000a900460ff161590508080156117c05750600160008054906101000a900460ff1660ff16105b806117ed57506117cf3061283a565b1580156117ec5750600160008054906101000a900460ff1660ff16145b5b61182c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611823906147b6565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611869576001600060016101000a81548160ff0219169083151502179055505b61187161285d565b6118796128b6565b6118d0600067ffffffffffffffff81111561189757611896613250565b5b6040519080825280602002602001820160405280156118ca57816020015b60608152602001906001900390816118b55790505b50612458565b80156119295760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516119209190614811565b60405180910390a15b50565b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61195a61220a565b61196261290f565b565b6099602052816000526040600020818051602081018201805184825260208301602085012081835280955050505050506000915091509054906101000a900460ff1681565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b609c5481565b6119e161220a565b60008103611a1b576040517f831761d700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609e819055507f6e8a187d7944998085dbd1f16b84c51c903bb727536cdba86962439aded2cfd7609e54604051611a5391906134be565b60405180910390a150565b609a60009054906101000a900463ffffffff1681565b611a7c612e92565b6000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3112a64846040518263ffffffff1660e01b8152600401611ad9919061302d565b600060405180830381865afa158015611af6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611b1f91906149f9565b905080915050919050565b611b3261220a565b6000801b8103611b6e576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609c819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611ba4919061302d565b60405180910390a150565b611bb761220a565b6000801b8103611bf3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609b819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611c29919061302d565b60405180910390a150565b609d60009054906101000a900467ffffffffffffffff1681565b609b5481565b611c5c61220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611cc2576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f663afa59423b5a718ce16629b25a640a45cf2f149146e62347cfc12b5a49b39f81604051611d329190613a91565b60405180910390a150565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630d2a3c0f846040518263ffffffff1660e01b8152600401611d9b9190613a91565b606060405180830381865afa158015611db8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddc9190614abb565b90506000816020015167ffffffffffffffff1603611e26576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e2f81612972565b806000015163ffffffff16915050919050565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7c7378b85856040518363ffffffff1660e01b8152600401611ea2929190614ae8565b606060405180830381865afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee39190614abb565b90506000816020015167ffffffffffffffff1603611f2d576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f3681612972565b806000015163ffffffff1691505092915050565b611f5261220a565b60008167ffffffffffffffff1603611f96576040517f91846b2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609d60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fadc24208c2c2249042b1d37e23d983fe99d452c60ebb70267b3a1274c49f9026609d60009054906101000a900467ffffffffffffffff166040516120049190614b42565b60405180910390a150565b61201761220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207d90614bcf565b60405180910390fd5b61208f81612774565b50565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5684609f546040518363ffffffff1660e01b81526004016120f492919061429c565b602060405180830381865afa158015612111573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213591906142da565b90506000801b81146121ed57600061214c82611a74565b90506000816060015167ffffffffffffffff1611801561217a575042816060015167ffffffffffffffff1611155b156121c05780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016121b79190613c81565b60405180910390fd5b60008161012001518060200190518101906121db9190614e20565b50505050509050809350505050612205565b60006121f884611d3d565b9050609e54811015925050505b919050565b612212612a08565b73ffffffffffffffffffffffffffffffffffffffff166122306119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227d90614f15565b60405180910390fd5b565b60006122b67f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612a10565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6122e761220a565b50565b6123167f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914360001b612a1a565b60000160009054906101000a900460ff161561233a5761233583612a24565b612453565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123a257506040513d601f19601f8201168201806040525081019061239f91906142da565b60015b6123e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123d890614fa7565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b8114612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90615039565b60405180910390fd5b50612452838383612add565b5b505050565b60005b81518110156124c457600082828151811061247957612478613f14565b5b602002602001015151036124b9576040517f88998c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600101905061245b565b508060986000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020908051906020019061250a929190612f3a565b5050565b612516612b09565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61255a612a08565b6040516125679190613a91565b60405180910390a1565b6060600061257e83611a74565b90506000816060015167ffffffffffffffff161180156125ac575042816060015167ffffffffffffffff1611155b156125f25780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016125e99190613c81565b60405180910390fd5b600081610120015180602001905181019061260d9190614e20565b955050505050506000815167ffffffffffffffff81111561263157612630613250565b5b60405190808252806020026020018201604052801561266a57816020015b612657612e53565b81526020019060019003908161264f5790505b50905060005b82518110156127685782818151811061268c5761268b613f14565b5b6020026020010151600001518282815181106126ab576126aa613f14565b5b6020026020010151600001819052506000801b8282815181106126d1576126d0613f14565b5b6020026020010151602001818152505083604001518282815181106126f9576126f8613f14565b5b60200260200101516040019067ffffffffffffffff16908167ffffffffffffffff1681525050836060015182828151811061273757612736613f14565b5b60200260200101516060019067ffffffffffffffff16908167ffffffffffffffff1681525050806001019050612670565b50809350505050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166128ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a3906150cb565b60405180910390fd5b6128b4612b52565b565b600060019054906101000a900460ff16612905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fc906150cb565b60405180910390fd5b61290d612bb3565b565b612917612c1f565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861295b612a08565b6040516129689190613a91565b60405180910390a1565b60008160400151905060008167ffffffffffffffff16036129b657609d60009054906101000a900467ffffffffffffffff1682602001516129b391906150eb565b90505b8067ffffffffffffffff164210612a0457806040517f06c094050000000000000000000000000000000000000000000000000000000081526004016129fb9190613c81565b60405180910390fd5b5050565b600033905090565b6000819050919050565b6000819050919050565b612a2d81612c69565b612a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6390615199565b60405180910390fd5b80612a997f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612a10565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b612ae683612c8c565b600082511180612af35750805b15612b0457612b028383612cdb565b505b505050565b612b116116b9565b612b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4790615205565b60405180910390fd5b565b600060019054906101000a900460ff16612ba1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b98906150cb565b60405180910390fd5b612bb1612bac612a08565b612774565b565b600060019054906101000a900460ff16612c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf9906150cb565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b612c276116b9565b15612c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5e90615271565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b612c9581612a24565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060612d00838360405180606001604052806027815260200161535160279139612d08565b905092915050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051612d3291906152cd565b600060405180830381855af49150503d8060008114612d6d576040519150601f19603f3d011682016040523d82523d6000602084013e612d72565b606091505b5091509150612d8386838387612d8e565b925050509392505050565b60608315612df0576000835103612de857612da885612c69565b612de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dde90615330565b60405180910390fd5b5b829050612dfb565b612dfa8383612e03565b5b949350505050565b600082511115612e165781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4a919061319e565b60405180910390fd5b60405180608001604052806060815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6040518061014001604052806000801916815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b828054828255906000526020600020908101928215612f82579160200282015b82811115612f81578251829081612f719190614138565b5091602001919060010190612f5a565b5b509050612f8f9190612f93565b5090565b5b80821115612fb35760008181612faa9190612fb7565b50600101612f94565b5090565b508054612fc390613d64565b6000825580601f10612fd55750612ff4565b601f016020900490600052602060002090810190612ff39190612ff7565b5b50565b5b80821115613010576000816000905550600101612ff8565b5090565b6000819050919050565b61302781613014565b82525050565b6000602082019050613042600083018461301e565b92915050565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b6130758161305c565b811461308057600080fd5b50565b6000813590506130928161306c565b92915050565b6000819050919050565b6130ab81613098565b81146130b657600080fd5b50565b6000813590506130c8816130a2565b92915050565b600080604083850312156130e5576130e4613052565b5b60006130f385828601613083565b9250506020613104858286016130b9565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561314857808201518184015260208101905061312d565b60008484015250505050565b6000601f19601f8301169050919050565b60006131708261310e565b61317a8185613119565b935061318a81856020860161312a565b61319381613154565b840191505092915050565b600060208201905081810360008301526131b88184613165565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131eb826131c0565b9050919050565b6131fb816131e0565b811461320657600080fd5b50565b600081359050613218816131f2565b92915050565b60006020828403121561323457613233613052565b5b600061324284828501613209565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61328882613154565b810181811067ffffffffffffffff821117156132a7576132a6613250565b5b80604052505050565b60006132ba613048565b90506132c6828261327f565b919050565b600067ffffffffffffffff8211156132e6576132e5613250565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff82111561331c5761331b613250565b5b61332582613154565b9050602081019050919050565b82818337600083830152505050565b600061335461334f84613301565b6132b0565b9050828152602081018484840111156133705761336f6132fc565b5b61337b848285613332565b509392505050565b600082601f8301126133985761339761324b565b5b81356133a8848260208601613341565b91505092915050565b60006133c46133bf846132cb565b6132b0565b905080838252602082019050602084028301858111156133e7576133e66132f7565b5b835b8181101561342e57803567ffffffffffffffff81111561340c5761340b61324b565b5b8086016134198982613383565b855260208501945050506020810190506133e9565b5050509392505050565b600082601f83011261344d5761344c61324b565b5b813561345d8482602086016133b1565b91505092915050565b60006020828403121561347c5761347b613052565b5b600082013567ffffffffffffffff81111561349a57613499613057565b5b6134a684828501613438565b91505092915050565b6134b881613098565b82525050565b60006020820190506134d360008301846134af565b92915050565b6000602082840312156134ef576134ee613052565b5b60006134fd84828501613083565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061354e8261310e565b6135588185613532565b935061356881856020860161312a565b61357181613154565b840191505092915050565b60006135888383613543565b905092915050565b6000602082019050919050565b60006135a882613506565b6135b28185613511565b9350836020820285016135c485613522565b8060005b8581101561360057848403895281516135e1858261357c565b94506135ec83613590565b925060208a019950506001810190506135c8565b50829750879550505050505092915050565b6000602082019050818103600083015261362c818461359d565b905092915050565b600067ffffffffffffffff82111561364f5761364e613250565b5b61365882613154565b9050602081019050919050565b600061367861367384613634565b6132b0565b905082815260208101848484011115613694576136936132fc565b5b61369f848285613332565b509392505050565b600082601f8301126136bc576136bb61324b565b5b81356136cc848260208601613665565b91505092915050565b600080604083850312156136ec576136eb613052565b5b60006136fa85828601613209565b925050602083013567ffffffffffffffff81111561371b5761371a613057565b5b613727858286016136a7565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61376681613014565b82525050565b600067ffffffffffffffff82169050919050565b6137898161376c565b82525050565b600060808301600083015184820360008601526137ac8282613543565b91505060208301516137c1602086018261375d565b5060408301516137d46040860182613780565b5060608301516137e76060860182613780565b508091505092915050565b60006137fe838361378f565b905092915050565b6000602082019050919050565b600061381e82613731565b613828818561373c565b93508360208202850161383a8561374d565b8060005b85811015613876578484038952815161385785826137f2565b945061386283613806565b925060208a0199505060018101905061383e565b50829750879550505050505092915050565b600060208201905081810360008301526138a28184613813565b905092915050565b60008115159050919050565b6138bf816138aa565b82525050565b60006020820190506138da60008301846138b6565b92915050565b6000819050919050565b60006139056139006138fb846131c0565b6138e0565b6131c0565b9050919050565b6000613917826138ea565b9050919050565b60006139298261390c565b9050919050565b6139398161391e565b82525050565b60006020820190506139546000830184613930565b92915050565b61396381613014565b811461396e57600080fd5b50565b6000813590506139808161395a565b92915050565b60006020828403121561399c5761399b613052565b5b60006139aa84828501613971565b91505092915050565b60006139be8261390c565b9050919050565b6139ce816139b3565b82525050565b60006020820190506139e960008301846139c5565b92915050565b60008060408385031215613a0657613a05613052565b5b6000613a1485828601613083565b925050602083013567ffffffffffffffff811115613a3557613a34613057565b5b613a4185828601613383565b9150509250929050565b600060ff82169050919050565b613a6181613a4b565b82525050565b6000602082019050613a7c6000830184613a58565b92915050565b613a8b816131e0565b82525050565b6000602082019050613aa66000830184613a82565b92915050565b600060208284031215613ac257613ac1613052565b5b6000613ad0848285016130b9565b91505092915050565b613ae28161305c565b82525050565b6000602082019050613afd6000830184613ad9565b92915050565b613b0c816131e0565b82525050565b613b1b816138aa565b82525050565b600081519050919050565b600082825260208201905092915050565b6000613b4882613b21565b613b528185613b2c565b9350613b6281856020860161312a565b613b6b81613154565b840191505092915050565b600061014083016000830151613b8f600086018261375d565b506020830151613ba2602086018261375d565b506040830151613bb56040860182613780565b506060830151613bc86060860182613780565b506080830151613bdb6080860182613780565b5060a0830151613bee60a086018261375d565b5060c0830151613c0160c0860182613b03565b5060e0830151613c1460e0860182613b03565b50610100830151613c29610100860182613b12565b50610120830151848203610120860152613c438282613b3d565b9150508091505092915050565b60006020820190508181036000830152613c6a8184613b76565b905092915050565b613c7b8161376c565b82525050565b6000602082019050613c966000830184613c72565b92915050565b60008060408385031215613cb357613cb2613052565b5b6000613cc185828601613083565b9250506020613cd285828601613209565b9150509250929050565b613ce58161376c565b8114613cf057600080fd5b50565b600081359050613d0281613cdc565b92915050565b600060208284031215613d1e57613d1d613052565b5b6000613d2c84828501613cf3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d7c57607f821691505b602082108103613d8f57613d8e613d35565b5b50919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b6000613df1602c83613119565b9150613dfc82613d95565b604082019050919050565b60006020820190508181036000830152613e2081613de4565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b6000613e83602c83613119565b9150613e8e82613e27565b604082019050919050565b60006020820190508181036000830152613eb281613e76565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613ef38261305c565b915063ffffffff8203613f0957613f08613eb9565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613f598261310e565b613f638185613f43565b9350613f7381856020860161312a565b80840191505092915050565b6000613f8b8284613f4e565b915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613ff87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613fbb565b6140028683613fbb565b95508019841693508086168417925050509392505050565b600061403561403061402b84613098565b6138e0565b613098565b9050919050565b6000819050919050565b61404f8361401a565b61406361405b8261403c565b848454613fc8565b825550505050565b600090565b61407861406b565b614083818484614046565b505050565b5b818110156140a75761409c600082614070565b600181019050614089565b5050565b601f8211156140ec576140bd81613f96565b6140c684613fab565b810160208510156140d5578190505b6140e96140e185613fab565b830182614088565b50505b505050565b600082821c905092915050565b600061410f600019846008026140f1565b1980831691505092915050565b600061412883836140fe565b9150826002028217905092915050565b6141418261310e565b67ffffffffffffffff81111561415a57614159613250565b5b6141648254613d64565b61416f8282856140ab565b600060209050601f8311600181146141a25760008415614190578287015190505b61419a858261411c565b865550614202565b601f1984166141b086613f96565b60005b828110156141d8578489015182556001820191506020850194506020810190506141b3565b868310156141f557848901516141f1601f8916826140fe565b8355505b6001600288020188555050505b505050505050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c60008201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b6000614266603883613119565b91506142718261420a565b604082019050919050565b6000602082019050818103600083015261429581614259565b9050919050565b60006040820190506142b16000830185613a82565b6142be602083018461301e565b9392505050565b6000815190506142d48161395a565b92915050565b6000602082840312156142f0576142ef613052565b5b60006142fe848285016142c5565b91505092915050565b600067ffffffffffffffff82111561432257614321613250565b5b602082029050602081019050919050565b600081519050614342816130a2565b92915050565b600061435b61435684614307565b6132b0565b9050808382526020820190506020840283018581111561437e5761437d6132f7565b5b835b818110156143a757806143938882614333565b845260208401935050602081019050614380565b5050509392505050565b600082601f8301126143c6576143c561324b565b5b81516143d6848260208601614348565b91505092915050565b600067ffffffffffffffff8211156143fa576143f9613250565b5b602082029050602081019050919050565b600061441e614419846143df565b6132b0565b90508083825260208201905060208402830185811115614441576144406132f7565b5b835b8181101561446a578061445688826142c5565b845260208401935050602081019050614443565b5050509392505050565b600082601f8301126144895761448861324b565b5b815161449984826020860161440b565b91505092915050565b600067ffffffffffffffff8211156144bd576144bc613250565b5b602082029050602081019050919050565b6000815190506144dd81613cdc565b92915050565b60006144f66144f1846144a2565b6132b0565b90508083825260208201905060208402830185811115614519576145186132f7565b5b835b81811015614542578061452e88826144ce565b84526020840193505060208101905061451b565b5050509392505050565b600082601f8301126145615761456061324b565b5b81516145718482602086016144e3565b91505092915050565b600061ffff82169050919050565b6145918161457a565b811461459c57600080fd5b50565b6000815190506145ae81614588565b92915050565b600080600080600060a086880312156145d0576145cf613052565b5b600086015167ffffffffffffffff8111156145ee576145ed613057565b5b6145fa888289016143b1565b955050602086015167ffffffffffffffff81111561461b5761461a613057565b5b61462788828901614474565b945050604086015167ffffffffffffffff81111561464857614647613057565b5b6146548882890161454c565b935050606086015167ffffffffffffffff81111561467557614674613057565b5b6146818882890161454c565b92505060806146928882890161459f565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60006146d982613098565b91506146e483613098565b92508282026146f281613098565b9150828204841483151761470957614708613eb9565b5b5092915050565b600061471b82613098565b915061472683613098565b925082820190508082111561473e5761473d613eb9565b5b92915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006147a0602e83613119565b91506147ab82614744565b604082019050919050565b600060208201905081810360008301526147cf81614793565b9050919050565b6000819050919050565b60006147fb6147f66147f1846147d6565b6138e0565b613a4b565b9050919050565b61480b816147e0565b82525050565b60006020820190506148266000830184614802565b92915050565b600080fd5b600080fd5b600081519050614845816131f2565b92915050565b614854816138aa565b811461485f57600080fd5b50565b6000815190506148718161484b565b92915050565b600061488a61488584613634565b6132b0565b9050828152602081018484840111156148a6576148a56132fc565b5b6148b184828561312a565b509392505050565b600082601f8301126148ce576148cd61324b565b5b81516148de848260208601614877565b91505092915050565b600061014082840312156148fe576148fd61482c565b5b6149096101406132b0565b90506000614919848285016142c5565b600083015250602061492d848285016142c5565b6020830152506040614941848285016144ce565b6040830152506060614955848285016144ce565b6060830152506080614969848285016144ce565b60808301525060a061497d848285016142c5565b60a08301525060c061499184828501614836565b60c08301525060e06149a584828501614836565b60e0830152506101006149ba84828501614862565b6101008301525061012082015167ffffffffffffffff8111156149e0576149df614831565b5b6149ec848285016148b9565b6101208301525092915050565b600060208284031215614a0f57614a0e613052565b5b600082015167ffffffffffffffff811115614a2d57614a2c613057565b5b614a39848285016148e7565b91505092915050565b600081519050614a518161306c565b92915050565b600060608284031215614a6d57614a6c61482c565b5b614a7760606132b0565b90506000614a8784828501614a42565b6000830152506020614a9b848285016144ce565b6020830152506040614aaf848285016144ce565b60408301525092915050565b600060608284031215614ad157614ad0613052565b5b6000614adf84828501614a57565b91505092915050565b6000604082019050614afd6000830185613ad9565b614b0a6020830184613a82565b9392505050565b6000614b2c614b27614b228461376c565b6138e0565b613098565b9050919050565b614b3c81614b11565b82525050565b6000602082019050614b576000830184614b33565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614bb9602683613119565b9150614bc482614b5d565b604082019050919050565b60006020820190508181036000830152614be881614bac565b9050919050565b614bf881613a4b565b8114614c0357600080fd5b50565b600081519050614c1581614bef565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b614c4081614c1b565b8114614c4b57600080fd5b50565b600081519050614c5d81614c37565b92915050565b600067ffffffffffffffff821115614c7e57614c7d613250565b5b602082029050602081019050919050565b6000614ca2614c9d84613301565b6132b0565b905082815260208101848484011115614cbe57614cbd6132fc565b5b614cc984828561312a565b509392505050565b600082601f830112614ce657614ce561324b565b5b8151614cf6848260208601614c8f565b91505092915050565b600060408284031215614d1557614d1461482c565b5b614d1f60406132b0565b9050600082015167ffffffffffffffff811115614d3f57614d3e614831565b5b614d4b84828501614cd1565b6000830152506020614d5f84828501614333565b60208301525092915050565b6000614d7e614d7984614c63565b6132b0565b90508083825260208201905060208402830185811115614da157614da06132f7565b5b835b81811015614de857805167ffffffffffffffff811115614dc657614dc561324b565b5b808601614dd38982614cff565b85526020850194505050602081019050614da3565b5050509392505050565b600082601f830112614e0757614e0661324b565b5b8151614e17848260208601614d6b565b91505092915050565b60008060008060008060c08789031215614e3d57614e3c613052565b5b6000614e4b89828a01614862565b9650506020614e5c89828a01614c06565b9550506040614e6d89828a01614c4e565b9450506060614e7e89828a01614a42565b9350506080614e8f89828a01614a42565b92505060a087015167ffffffffffffffff811115614eb057614eaf613057565b5b614ebc89828a01614df2565b9150509295509295509295565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614eff602083613119565b9150614f0a82614ec9565b602082019050919050565b60006020820190508181036000830152614f2e81614ef2565b9050919050565b7f45524331393637557067726164653a206e657720696d706c656d656e7461746960008201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b6000614f91602e83613119565b9150614f9c82614f35565b604082019050919050565b60006020820190508181036000830152614fc081614f84565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f7860008201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b6000615023602983613119565b915061502e82614fc7565b604082019050919050565b6000602082019050818103600083015261505281615016565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b60006150b5602b83613119565b91506150c082615059565b604082019050919050565b600060208201905081810360008301526150e4816150a8565b9050919050565b60006150f68261376c565b91506151018361376c565b9250828201905067ffffffffffffffff81111561512157615120613eb9565b5b92915050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b6000615183602d83613119565b915061518e82615127565b604082019050919050565b600060208201905081810360008301526151b281615176565b9050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b60006151ef601483613119565b91506151fa826151b9565b602082019050919050565b6000602082019050818103600083015261521e816151e2565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b600061525b601083613119565b915061526682615225565b602082019050919050565b6000602082019050818103600083015261528a8161524e565b9050919050565b600081905092915050565b60006152a782613b21565b6152b18185615291565b93506152c181856020860161312a565b80840191505092915050565b60006152d9828461529c565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600061531a601d83613119565b9150615325826152e4565b602082019050919050565b600060208201905081810360008301526153498161530d565b905091905056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bbf06b6163a3b4bfa17cb8d84cf98632ab690d1effb7062541e386cf055d830064736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102045760003560e01c80638150864d11610118578063bb169f7f116100a0578063d47875d01161006f578063d47875d0146106fc578063daadd66214610739578063e4a5920914610776578063f2fde38b1461079f578063f72c436f146107c857610204565b8063bb169f7f14610654578063c82bfbb71461067d578063ceab3988146106a8578063d2ae372c146106d357610204565b806391c70059116100e757806391c700591461056f578063960bfe041461059a5780639d888e86146105c3578063a3112a64146105ee578063a46767b51461062b57610204565b80638150864d146104c55780638456cb59146104f057806386b69e8a146105075780638da5cb5b1461054457610204565b80634e62cf3f1161019b5780635c975abb1161016a5780635c975abb146104185780635e33ef5d146104435780636edbe6da1461046e578063715018a6146104975780638129fc1c146104ae57610204565b80634e62cf3f146103575780634f1ef2861461039457806352d1902d146103b057806357a5893c146103db57610204565b80633923d3ef116101d75780633923d3ef146102c35780633f4ba83a146102ec578063420b75891461030357806342cde4e81461032c57610204565b806315e94078146102095780631cd191e8146102345780632e314f65146102715780633659cfe61461029a575b600080fd5b34801561021557600080fd5b5061021e610805565b60405161022b919061302d565b60405180910390f35b34801561024057600080fd5b5061025b600480360381019061025691906130ce565b61080b565b604051610268919061319e565b60405180910390f35b34801561027d57600080fd5b506102986004803603810190610293919061321e565b6108c4565b005b3480156102a657600080fd5b506102c160048036038101906102bc919061321e565b6109ad565b005b3480156102cf57600080fd5b506102ea60048036038101906102e59190613466565b610b35565b005b3480156102f857600080fd5b50610301610bb6565b005b34801561030f57600080fd5b5061032a60048036038101906103259190613466565b610bc8565b005b34801561033857600080fd5b50610341610e4c565b60405161034e91906134be565b60405180910390f35b34801561036357600080fd5b5061037e600480360381019061037991906134d9565b610e52565b60405161038b9190613612565b60405180910390f35b6103ae60048036038101906103a991906136d5565b610f4a565b005b3480156103bc57600080fd5b506103c5611086565b6040516103d2919061302d565b60405180910390f35b3480156103e757600080fd5b5061040260048036038101906103fd919061321e565b61113f565b60405161040f9190613888565b60405180910390f35b34801561042457600080fd5b5061042d6116b9565b60405161043a91906138c5565b60405180910390f35b34801561044f57600080fd5b506104586116d0565b604051610465919061393f565b60405180910390f35b34801561047a57600080fd5b5061049560048036038101906104909190613986565b6116f6565b005b3480156104a357600080fd5b506104ac61177b565b005b3480156104ba57600080fd5b506104c361178f565b005b3480156104d157600080fd5b506104da61192c565b6040516104e791906139d4565b60405180910390f35b3480156104fc57600080fd5b50610505611952565b005b34801561051357600080fd5b5061052e600480360381019061052991906139ef565b611964565b60405161053b9190613a67565b60405180910390f35b34801561055057600080fd5b506105596119a9565b6040516105669190613a91565b60405180910390f35b34801561057b57600080fd5b506105846119d3565b604051610591919061302d565b60405180910390f35b3480156105a657600080fd5b506105c160048036038101906105bc9190613aac565b6119d9565b005b3480156105cf57600080fd5b506105d8611a5e565b6040516105e59190613ae8565b60405180910390f35b3480156105fa57600080fd5b5061061560048036038101906106109190613986565b611a74565b6040516106229190613c50565b60405180910390f35b34801561063757600080fd5b50610652600480360381019061064d9190613986565b611b2a565b005b34801561066057600080fd5b5061067b60048036038101906106769190613986565b611baf565b005b34801561068957600080fd5b50610692611c34565b60405161069f9190613c81565b60405180910390f35b3480156106b457600080fd5b506106bd611c4e565b6040516106ca919061302d565b60405180910390f35b3480156106df57600080fd5b506106fa60048036038101906106f5919061321e565b611c54565b005b34801561070857600080fd5b50610723600480360381019061071e919061321e565b611d3d565b60405161073091906134be565b60405180910390f35b34801561074557600080fd5b50610760600480360381019061075b9190613c9c565b611e42565b60405161076d91906134be565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613d08565b611f4a565b005b3480156107ab57600080fd5b506107c660048036038101906107c1919061321e565b61200f565b005b3480156107d457600080fd5b506107ef60048036038101906107ea919061321e565b612092565b6040516107fc91906138c5565b60405180910390f35b609f5481565b6098602052816000526040600020818154811061082757600080fd5b9060005260206000200160009150915050805461084390613d64565b80601f016020809104026020016040519081016040528092919081815260200182805461086f90613d64565b80156108bc5780601f10610891576101008083540402835291602001916108bc565b820191906000526020600020905b81548152906001019060200180831161089f57829003601f168201915b505050505081565b6108cc61220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610932576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609a60046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f14dc79d338b451b8b7b20e3191752ac97cbc8b011ff3b921597b83b1222896ae816040516109a29190613a91565b60405180910390a150565b7f00000000000000000000000090e2c4472df225e8d31f44725b75ffaa244d5d3373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613e07565b60405180910390fd5b7f00000000000000000000000090e2c4472df225e8d31f44725b75ffaa244d5d3373ffffffffffffffffffffffffffffffffffffffff16610a7a612288565b73ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790613e99565b60405180910390fd5b610ad9816122df565b610b3281600067ffffffffffffffff811115610af857610af7613250565b5b6040519080825280601f01601f191660200182016040528015610b2a5781602001600182028036833780820191505090505b5060006122ea565b50565b610b3d61220a565b609a600081819054906101000a900463ffffffff1680929190610b5f90613ee8565b91906101000a81548163ffffffff021916908363ffffffff16021790555050610b8781612458565b7f4e210ed25abf187b8a2f6c516deef88d958c75e285b05928d7db0f8a673ce25f60405160405180910390a150565b610bbe61220a565b610bc661250e565b565b610bd061220a565b60005b8151811015610e11576000828281518110610bf157610bf0613f14565b5b60200260200101515103610c31576040517f88998c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160996000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020838381518110610c7757610c76613f14565b5b6020026020010151604051610c8c9190613f7f565b908152602001604051809103902060009054906101000a900460ff1660ff1603610d0757818181518110610cc357610cc2613f14565b5b60200260200101516040517fee118ba6000000000000000000000000000000000000000000000000000000008152600401610cfe919061319e565b60405180910390fd5b60986000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020828281518110610d4b57610d4a613f14565b5b6020026020010151908060018154018082558091505060019003906000526020600020016000909190919091509081610d849190614138565b50600160996000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020838381518110610dcb57610dca613f14565b5b6020026020010151604051610de09190613f7f565b908152602001604051809103902060006101000a81548160ff021916908360ff160217905550806001019050610bd3565b507fec76e5d73810a27d70d44fe10dd9040c9c446187c33df2ae02ceb4b07cfa7eb781604051610e419190613612565b60405180910390a150565b609e5481565b6060609860008363ffffffff1663ffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f3f578382906000526020600020018054610eb290613d64565b80601f0160208091040260200160405190810160405280929190818152602001828054610ede90613d64565b8015610f2b5780601f10610f0057610100808354040283529160200191610f2b565b820191906000526020600020905b815481529060010190602001808311610f0e57829003601f168201915b505050505081526020019060010190610e93565b505050509050919050565b7f00000000000000000000000090e2c4472df225e8d31f44725b75ffaa244d5d3373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf90613e07565b60405180910390fd5b7f00000000000000000000000090e2c4472df225e8d31f44725b75ffaa244d5d3373ffffffffffffffffffffffffffffffffffffffff16611017612288565b73ffffffffffffffffffffffffffffffffffffffff161461106d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106490613e99565b60405180910390fd5b611076826122df565b611082828260016122ea565b5050565b60007f00000000000000000000000090e2c4472df225e8d31f44725b75ffaa244d5d3373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611116576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110d9061427c565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905090565b60606000609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5684609f546040518363ffffffff1660e01b81526004016111a292919061429c565b602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e391906142da565b90506000801b8114611200576111f881612571565b9150506116b4565b6000609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5685609b546040518363ffffffff1660e01b815260040161126192919061429c565b602060405180830381865afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a291906142da565b90506000801b81036112e0576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006112eb82611a74565b90506000816060015167ffffffffffffffff16118015611319575042816060015167ffffffffffffffff1611155b1561135f5780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016113569190613c81565b60405180910390fd5b606080606080600085610120015180602001905181019061138091906145b4565b8095508196508297508398508499505050505050600080600090506000609860008561ffff1663ffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156114865783829060005260206000200180546113f990613d64565b80601f016020809104026020016040519081016040528092919081815260200182805461142590613d64565b80156114725780601f1061144757610100808354040283529160200191611472565b820191906000526020600020905b81548152906001019060200180831161145557829003601f168201915b5050505050815260200190600101906113da565b5050505090506000875190506000895190506000835190508851831480156114ae5750875183145b6114bb576114ba61469f565b5b60008367ffffffffffffffff8111156114d7576114d6613250565b5b60405190808252806020026020018201604052801561151057816020015b6114fd612e53565b8152602001906001900390816114f55790505b50905060005b838110156116a0576001975060008d828151811061153757611536613f14565b5b6020026020010151905060005b6101008110156116925786891015611692576000816101008561156791906146ce565b6115719190614710565b9050858111156115815750611692565b60008b8416111561167f57611594612e53565b8982815181106115a7576115a6613f14565b5b602002602001015181600001819052508f8b815181106115ca576115c9613f14565b5b60200260200101518160200181815250508e8b815181106115ee576115ed613f14565b5b6020026020010151816040019067ffffffffffffffff16908167ffffffffffffffff16815250508d8b8151811061162857611627613f14565b5b6020026020010151816060019067ffffffffffffffff16908167ffffffffffffffff168152505080868c8151811061166357611662613f14565b5b602002602001018190525060018b61167b9190614710565b9a50505b60018b901b9a5081600101915050611544565b506101008201915050611516565b50809f505050505050505050505050505050505b919050565b6000606560009054906101000a900460ff16905090565b609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6116fe61220a565b6000801b810361173a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609f819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611770919061302d565b60405180910390a150565b61178361220a565b61178d6000612774565b565b60008060019054906101000a900460ff161590508080156117c05750600160008054906101000a900460ff1660ff16105b806117ed57506117cf3061283a565b1580156117ec5750600160008054906101000a900460ff1660ff16145b5b61182c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611823906147b6565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611869576001600060016101000a81548160ff0219169083151502179055505b61187161285d565b6118796128b6565b6118d0600067ffffffffffffffff81111561189757611896613250565b5b6040519080825280602002602001820160405280156118ca57816020015b60608152602001906001900390816118b55790505b50612458565b80156119295760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516119209190614811565b60405180910390a15b50565b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61195a61220a565b61196261290f565b565b6099602052816000526040600020818051602081018201805184825260208301602085012081835280955050505050506000915091509054906101000a900460ff1681565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b609c5481565b6119e161220a565b60008103611a1b576040517f831761d700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609e819055507f6e8a187d7944998085dbd1f16b84c51c903bb727536cdba86962439aded2cfd7609e54604051611a5391906134be565b60405180910390a150565b609a60009054906101000a900463ffffffff1681565b611a7c612e92565b6000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3112a64846040518263ffffffff1660e01b8152600401611ad9919061302d565b600060405180830381865afa158015611af6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611b1f91906149f9565b905080915050919050565b611b3261220a565b6000801b8103611b6e576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609c819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611ba4919061302d565b60405180910390a150565b611bb761220a565b6000801b8103611bf3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609b819055507feffcfd1add745716a37d406c77e2b9102d465752c93eab2cb1aa1d2e50a08f2f81604051611c29919061302d565b60405180910390a150565b609d60009054906101000a900467ffffffffffffffff1681565b609b5481565b611c5c61220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611cc2576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f663afa59423b5a718ce16629b25a640a45cf2f149146e62347cfc12b5a49b39f81604051611d329190613a91565b60405180910390a150565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630d2a3c0f846040518263ffffffff1660e01b8152600401611d9b9190613a91565b606060405180830381865afa158015611db8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddc9190614abb565b90506000816020015167ffffffffffffffff1603611e26576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e2f81612972565b806000015163ffffffff16915050919050565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7c7378b85856040518363ffffffff1660e01b8152600401611ea2929190614ae8565b606060405180830381865afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee39190614abb565b90506000816020015167ffffffffffffffff1603611f2d576040517f120a2e7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f3681612972565b806000015163ffffffff1691505092915050565b611f5261220a565b60008167ffffffffffffffff1603611f96576040517f91846b2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80609d60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fadc24208c2c2249042b1d37e23d983fe99d452c60ebb70267b3a1274c49f9026609d60009054906101000a900467ffffffffffffffff166040516120049190614b42565b60405180910390a150565b61201761220a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207d90614bcf565b60405180910390fd5b61208f81612774565b50565b600080609a60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379300e5684609f546040518363ffffffff1660e01b81526004016120f492919061429c565b602060405180830381865afa158015612111573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213591906142da565b90506000801b81146121ed57600061214c82611a74565b90506000816060015167ffffffffffffffff1611801561217a575042816060015167ffffffffffffffff1611155b156121c05780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016121b79190613c81565b60405180910390fd5b60008161012001518060200190518101906121db9190614e20565b50505050509050809350505050612205565b60006121f884611d3d565b9050609e54811015925050505b919050565b612212612a08565b73ffffffffffffffffffffffffffffffffffffffff166122306119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227d90614f15565b60405180910390fd5b565b60006122b67f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612a10565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6122e761220a565b50565b6123167f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914360001b612a1a565b60000160009054906101000a900460ff161561233a5761233583612a24565b612453565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123a257506040513d601f19601f8201168201806040525081019061239f91906142da565b60015b6123e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123d890614fa7565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b8114612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90615039565b60405180910390fd5b50612452838383612add565b5b505050565b60005b81518110156124c457600082828151811061247957612478613f14565b5b602002602001015151036124b9576040517f88998c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600101905061245b565b508060986000609a60009054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020908051906020019061250a929190612f3a565b5050565b612516612b09565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61255a612a08565b6040516125679190613a91565b60405180910390a1565b6060600061257e83611a74565b90506000816060015167ffffffffffffffff161180156125ac575042816060015167ffffffffffffffff1611155b156125f25780606001516040517f06c094050000000000000000000000000000000000000000000000000000000081526004016125e99190613c81565b60405180910390fd5b600081610120015180602001905181019061260d9190614e20565b955050505050506000815167ffffffffffffffff81111561263157612630613250565b5b60405190808252806020026020018201604052801561266a57816020015b612657612e53565b81526020019060019003908161264f5790505b50905060005b82518110156127685782818151811061268c5761268b613f14565b5b6020026020010151600001518282815181106126ab576126aa613f14565b5b6020026020010151600001819052506000801b8282815181106126d1576126d0613f14565b5b6020026020010151602001818152505083604001518282815181106126f9576126f8613f14565b5b60200260200101516040019067ffffffffffffffff16908167ffffffffffffffff1681525050836060015182828151811061273757612736613f14565b5b60200260200101516060019067ffffffffffffffff16908167ffffffffffffffff1681525050806001019050612670565b50809350505050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166128ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a3906150cb565b60405180910390fd5b6128b4612b52565b565b600060019054906101000a900460ff16612905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fc906150cb565b60405180910390fd5b61290d612bb3565b565b612917612c1f565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861295b612a08565b6040516129689190613a91565b60405180910390a1565b60008160400151905060008167ffffffffffffffff16036129b657609d60009054906101000a900467ffffffffffffffff1682602001516129b391906150eb565b90505b8067ffffffffffffffff164210612a0457806040517f06c094050000000000000000000000000000000000000000000000000000000081526004016129fb9190613c81565b60405180910390fd5b5050565b600033905090565b6000819050919050565b6000819050919050565b612a2d81612c69565b612a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6390615199565b60405180910390fd5b80612a997f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612a10565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b612ae683612c8c565b600082511180612af35750805b15612b0457612b028383612cdb565b505b505050565b612b116116b9565b612b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4790615205565b60405180910390fd5b565b600060019054906101000a900460ff16612ba1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b98906150cb565b60405180910390fd5b612bb1612bac612a08565b612774565b565b600060019054906101000a900460ff16612c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf9906150cb565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b612c276116b9565b15612c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5e90615271565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b612c9581612a24565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060612d00838360405180606001604052806027815260200161535160279139612d08565b905092915050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051612d3291906152cd565b600060405180830381855af49150503d8060008114612d6d576040519150601f19603f3d011682016040523d82523d6000602084013e612d72565b606091505b5091509150612d8386838387612d8e565b925050509392505050565b60608315612df0576000835103612de857612da885612c69565b612de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dde90615330565b60405180910390fd5b5b829050612dfb565b612dfa8383612e03565b5b949350505050565b600082511115612e165781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4a919061319e565b60405180910390fd5b60405180608001604052806060815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6040518061014001604052806000801916815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b828054828255906000526020600020908101928215612f82579160200282015b82811115612f81578251829081612f719190614138565b5091602001919060010190612f5a565b5b509050612f8f9190612f93565b5090565b5b80821115612fb35760008181612faa9190612fb7565b50600101612f94565b5090565b508054612fc390613d64565b6000825580601f10612fd55750612ff4565b601f016020900490600052602060002090810190612ff39190612ff7565b5b50565b5b80821115613010576000816000905550600101612ff8565b5090565b6000819050919050565b61302781613014565b82525050565b6000602082019050613042600083018461301e565b92915050565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b6130758161305c565b811461308057600080fd5b50565b6000813590506130928161306c565b92915050565b6000819050919050565b6130ab81613098565b81146130b657600080fd5b50565b6000813590506130c8816130a2565b92915050565b600080604083850312156130e5576130e4613052565b5b60006130f385828601613083565b9250506020613104858286016130b9565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561314857808201518184015260208101905061312d565b60008484015250505050565b6000601f19601f8301169050919050565b60006131708261310e565b61317a8185613119565b935061318a81856020860161312a565b61319381613154565b840191505092915050565b600060208201905081810360008301526131b88184613165565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131eb826131c0565b9050919050565b6131fb816131e0565b811461320657600080fd5b50565b600081359050613218816131f2565b92915050565b60006020828403121561323457613233613052565b5b600061324284828501613209565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61328882613154565b810181811067ffffffffffffffff821117156132a7576132a6613250565b5b80604052505050565b60006132ba613048565b90506132c6828261327f565b919050565b600067ffffffffffffffff8211156132e6576132e5613250565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff82111561331c5761331b613250565b5b61332582613154565b9050602081019050919050565b82818337600083830152505050565b600061335461334f84613301565b6132b0565b9050828152602081018484840111156133705761336f6132fc565b5b61337b848285613332565b509392505050565b600082601f8301126133985761339761324b565b5b81356133a8848260208601613341565b91505092915050565b60006133c46133bf846132cb565b6132b0565b905080838252602082019050602084028301858111156133e7576133e66132f7565b5b835b8181101561342e57803567ffffffffffffffff81111561340c5761340b61324b565b5b8086016134198982613383565b855260208501945050506020810190506133e9565b5050509392505050565b600082601f83011261344d5761344c61324b565b5b813561345d8482602086016133b1565b91505092915050565b60006020828403121561347c5761347b613052565b5b600082013567ffffffffffffffff81111561349a57613499613057565b5b6134a684828501613438565b91505092915050565b6134b881613098565b82525050565b60006020820190506134d360008301846134af565b92915050565b6000602082840312156134ef576134ee613052565b5b60006134fd84828501613083565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061354e8261310e565b6135588185613532565b935061356881856020860161312a565b61357181613154565b840191505092915050565b60006135888383613543565b905092915050565b6000602082019050919050565b60006135a882613506565b6135b28185613511565b9350836020820285016135c485613522565b8060005b8581101561360057848403895281516135e1858261357c565b94506135ec83613590565b925060208a019950506001810190506135c8565b50829750879550505050505092915050565b6000602082019050818103600083015261362c818461359d565b905092915050565b600067ffffffffffffffff82111561364f5761364e613250565b5b61365882613154565b9050602081019050919050565b600061367861367384613634565b6132b0565b905082815260208101848484011115613694576136936132fc565b5b61369f848285613332565b509392505050565b600082601f8301126136bc576136bb61324b565b5b81356136cc848260208601613665565b91505092915050565b600080604083850312156136ec576136eb613052565b5b60006136fa85828601613209565b925050602083013567ffffffffffffffff81111561371b5761371a613057565b5b613727858286016136a7565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61376681613014565b82525050565b600067ffffffffffffffff82169050919050565b6137898161376c565b82525050565b600060808301600083015184820360008601526137ac8282613543565b91505060208301516137c1602086018261375d565b5060408301516137d46040860182613780565b5060608301516137e76060860182613780565b508091505092915050565b60006137fe838361378f565b905092915050565b6000602082019050919050565b600061381e82613731565b613828818561373c565b93508360208202850161383a8561374d565b8060005b85811015613876578484038952815161385785826137f2565b945061386283613806565b925060208a0199505060018101905061383e565b50829750879550505050505092915050565b600060208201905081810360008301526138a28184613813565b905092915050565b60008115159050919050565b6138bf816138aa565b82525050565b60006020820190506138da60008301846138b6565b92915050565b6000819050919050565b60006139056139006138fb846131c0565b6138e0565b6131c0565b9050919050565b6000613917826138ea565b9050919050565b60006139298261390c565b9050919050565b6139398161391e565b82525050565b60006020820190506139546000830184613930565b92915050565b61396381613014565b811461396e57600080fd5b50565b6000813590506139808161395a565b92915050565b60006020828403121561399c5761399b613052565b5b60006139aa84828501613971565b91505092915050565b60006139be8261390c565b9050919050565b6139ce816139b3565b82525050565b60006020820190506139e960008301846139c5565b92915050565b60008060408385031215613a0657613a05613052565b5b6000613a1485828601613083565b925050602083013567ffffffffffffffff811115613a3557613a34613057565b5b613a4185828601613383565b9150509250929050565b600060ff82169050919050565b613a6181613a4b565b82525050565b6000602082019050613a7c6000830184613a58565b92915050565b613a8b816131e0565b82525050565b6000602082019050613aa66000830184613a82565b92915050565b600060208284031215613ac257613ac1613052565b5b6000613ad0848285016130b9565b91505092915050565b613ae28161305c565b82525050565b6000602082019050613afd6000830184613ad9565b92915050565b613b0c816131e0565b82525050565b613b1b816138aa565b82525050565b600081519050919050565b600082825260208201905092915050565b6000613b4882613b21565b613b528185613b2c565b9350613b6281856020860161312a565b613b6b81613154565b840191505092915050565b600061014083016000830151613b8f600086018261375d565b506020830151613ba2602086018261375d565b506040830151613bb56040860182613780565b506060830151613bc86060860182613780565b506080830151613bdb6080860182613780565b5060a0830151613bee60a086018261375d565b5060c0830151613c0160c0860182613b03565b5060e0830151613c1460e0860182613b03565b50610100830151613c29610100860182613b12565b50610120830151848203610120860152613c438282613b3d565b9150508091505092915050565b60006020820190508181036000830152613c6a8184613b76565b905092915050565b613c7b8161376c565b82525050565b6000602082019050613c966000830184613c72565b92915050565b60008060408385031215613cb357613cb2613052565b5b6000613cc185828601613083565b9250506020613cd285828601613209565b9150509250929050565b613ce58161376c565b8114613cf057600080fd5b50565b600081359050613d0281613cdc565b92915050565b600060208284031215613d1e57613d1d613052565b5b6000613d2c84828501613cf3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d7c57607f821691505b602082108103613d8f57613d8e613d35565b5b50919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b6000613df1602c83613119565b9150613dfc82613d95565b604082019050919050565b60006020820190508181036000830152613e2081613de4565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b6000613e83602c83613119565b9150613e8e82613e27565b604082019050919050565b60006020820190508181036000830152613eb281613e76565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613ef38261305c565b915063ffffffff8203613f0957613f08613eb9565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613f598261310e565b613f638185613f43565b9350613f7381856020860161312a565b80840191505092915050565b6000613f8b8284613f4e565b915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613ff87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613fbb565b6140028683613fbb565b95508019841693508086168417925050509392505050565b600061403561403061402b84613098565b6138e0565b613098565b9050919050565b6000819050919050565b61404f8361401a565b61406361405b8261403c565b848454613fc8565b825550505050565b600090565b61407861406b565b614083818484614046565b505050565b5b818110156140a75761409c600082614070565b600181019050614089565b5050565b601f8211156140ec576140bd81613f96565b6140c684613fab565b810160208510156140d5578190505b6140e96140e185613fab565b830182614088565b50505b505050565b600082821c905092915050565b600061410f600019846008026140f1565b1980831691505092915050565b600061412883836140fe565b9150826002028217905092915050565b6141418261310e565b67ffffffffffffffff81111561415a57614159613250565b5b6141648254613d64565b61416f8282856140ab565b600060209050601f8311600181146141a25760008415614190578287015190505b61419a858261411c565b865550614202565b601f1984166141b086613f96565b60005b828110156141d8578489015182556001820191506020850194506020810190506141b3565b868310156141f557848901516141f1601f8916826140fe565b8355505b6001600288020188555050505b505050505050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c60008201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b6000614266603883613119565b91506142718261420a565b604082019050919050565b6000602082019050818103600083015261429581614259565b9050919050565b60006040820190506142b16000830185613a82565b6142be602083018461301e565b9392505050565b6000815190506142d48161395a565b92915050565b6000602082840312156142f0576142ef613052565b5b60006142fe848285016142c5565b91505092915050565b600067ffffffffffffffff82111561432257614321613250565b5b602082029050602081019050919050565b600081519050614342816130a2565b92915050565b600061435b61435684614307565b6132b0565b9050808382526020820190506020840283018581111561437e5761437d6132f7565b5b835b818110156143a757806143938882614333565b845260208401935050602081019050614380565b5050509392505050565b600082601f8301126143c6576143c561324b565b5b81516143d6848260208601614348565b91505092915050565b600067ffffffffffffffff8211156143fa576143f9613250565b5b602082029050602081019050919050565b600061441e614419846143df565b6132b0565b90508083825260208201905060208402830185811115614441576144406132f7565b5b835b8181101561446a578061445688826142c5565b845260208401935050602081019050614443565b5050509392505050565b600082601f8301126144895761448861324b565b5b815161449984826020860161440b565b91505092915050565b600067ffffffffffffffff8211156144bd576144bc613250565b5b602082029050602081019050919050565b6000815190506144dd81613cdc565b92915050565b60006144f66144f1846144a2565b6132b0565b90508083825260208201905060208402830185811115614519576145186132f7565b5b835b81811015614542578061452e88826144ce565b84526020840193505060208101905061451b565b5050509392505050565b600082601f8301126145615761456061324b565b5b81516145718482602086016144e3565b91505092915050565b600061ffff82169050919050565b6145918161457a565b811461459c57600080fd5b50565b6000815190506145ae81614588565b92915050565b600080600080600060a086880312156145d0576145cf613052565b5b600086015167ffffffffffffffff8111156145ee576145ed613057565b5b6145fa888289016143b1565b955050602086015167ffffffffffffffff81111561461b5761461a613057565b5b61462788828901614474565b945050604086015167ffffffffffffffff81111561464857614647613057565b5b6146548882890161454c565b935050606086015167ffffffffffffffff81111561467557614674613057565b5b6146818882890161454c565b92505060806146928882890161459f565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60006146d982613098565b91506146e483613098565b92508282026146f281613098565b9150828204841483151761470957614708613eb9565b5b5092915050565b600061471b82613098565b915061472683613098565b925082820190508082111561473e5761473d613eb9565b5b92915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006147a0602e83613119565b91506147ab82614744565b604082019050919050565b600060208201905081810360008301526147cf81614793565b9050919050565b6000819050919050565b60006147fb6147f66147f1846147d6565b6138e0565b613a4b565b9050919050565b61480b816147e0565b82525050565b60006020820190506148266000830184614802565b92915050565b600080fd5b600080fd5b600081519050614845816131f2565b92915050565b614854816138aa565b811461485f57600080fd5b50565b6000815190506148718161484b565b92915050565b600061488a61488584613634565b6132b0565b9050828152602081018484840111156148a6576148a56132fc565b5b6148b184828561312a565b509392505050565b600082601f8301126148ce576148cd61324b565b5b81516148de848260208601614877565b91505092915050565b600061014082840312156148fe576148fd61482c565b5b6149096101406132b0565b90506000614919848285016142c5565b600083015250602061492d848285016142c5565b6020830152506040614941848285016144ce565b6040830152506060614955848285016144ce565b6060830152506080614969848285016144ce565b60808301525060a061497d848285016142c5565b60a08301525060c061499184828501614836565b60c08301525060e06149a584828501614836565b60e0830152506101006149ba84828501614862565b6101008301525061012082015167ffffffffffffffff8111156149e0576149df614831565b5b6149ec848285016148b9565b6101208301525092915050565b600060208284031215614a0f57614a0e613052565b5b600082015167ffffffffffffffff811115614a2d57614a2c613057565b5b614a39848285016148e7565b91505092915050565b600081519050614a518161306c565b92915050565b600060608284031215614a6d57614a6c61482c565b5b614a7760606132b0565b90506000614a8784828501614a42565b6000830152506020614a9b848285016144ce565b6020830152506040614aaf848285016144ce565b60408301525092915050565b600060608284031215614ad157614ad0613052565b5b6000614adf84828501614a57565b91505092915050565b6000604082019050614afd6000830185613ad9565b614b0a6020830184613a82565b9392505050565b6000614b2c614b27614b228461376c565b6138e0565b613098565b9050919050565b614b3c81614b11565b82525050565b6000602082019050614b576000830184614b33565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614bb9602683613119565b9150614bc482614b5d565b604082019050919050565b60006020820190508181036000830152614be881614bac565b9050919050565b614bf881613a4b565b8114614c0357600080fd5b50565b600081519050614c1581614bef565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b614c4081614c1b565b8114614c4b57600080fd5b50565b600081519050614c5d81614c37565b92915050565b600067ffffffffffffffff821115614c7e57614c7d613250565b5b602082029050602081019050919050565b6000614ca2614c9d84613301565b6132b0565b905082815260208101848484011115614cbe57614cbd6132fc565b5b614cc984828561312a565b509392505050565b600082601f830112614ce657614ce561324b565b5b8151614cf6848260208601614c8f565b91505092915050565b600060408284031215614d1557614d1461482c565b5b614d1f60406132b0565b9050600082015167ffffffffffffffff811115614d3f57614d3e614831565b5b614d4b84828501614cd1565b6000830152506020614d5f84828501614333565b60208301525092915050565b6000614d7e614d7984614c63565b6132b0565b90508083825260208201905060208402830185811115614da157614da06132f7565b5b835b81811015614de857805167ffffffffffffffff811115614dc657614dc561324b565b5b808601614dd38982614cff565b85526020850194505050602081019050614da3565b5050509392505050565b600082601f830112614e0757614e0661324b565b5b8151614e17848260208601614d6b565b91505092915050565b60008060008060008060c08789031215614e3d57614e3c613052565b5b6000614e4b89828a01614862565b9650506020614e5c89828a01614c06565b9550506040614e6d89828a01614c4e565b9450506060614e7e89828a01614a42565b9350506080614e8f89828a01614a42565b92505060a087015167ffffffffffffffff811115614eb057614eaf613057565b5b614ebc89828a01614df2565b9150509295509295509295565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614eff602083613119565b9150614f0a82614ec9565b602082019050919050565b60006020820190508181036000830152614f2e81614ef2565b9050919050565b7f45524331393637557067726164653a206e657720696d706c656d656e7461746960008201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b6000614f91602e83613119565b9150614f9c82614f35565b604082019050919050565b60006020820190508181036000830152614fc081614f84565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f7860008201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b6000615023602983613119565b915061502e82614fc7565b604082019050919050565b6000602082019050818103600083015261505281615016565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b60006150b5602b83613119565b91506150c082615059565b604082019050919050565b600060208201905081810360008301526150e4816150a8565b9050919050565b60006150f68261376c565b91506151018361376c565b9250828201905067ffffffffffffffff81111561512157615120613eb9565b5b92915050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b6000615183602d83613119565b915061518e82615127565b604082019050919050565b600060208201905081810360008301526151b281615176565b9050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b60006151ef601483613119565b91506151fa826151b9565b602082019050919050565b6000602082019050818103600083015261521e816151e2565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b600061525b601083613119565b915061526682615225565b602082019050919050565b6000602082019050818103600083015261528a8161524e565b9050919050565b600081905092915050565b60006152a782613b21565b6152b18185615291565b93506152c181856020860161312a565b80840191505092915050565b60006152d9828461529c565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600061531a601d83613119565b9150615325826152e4565b602082019050919050565b600060208201905081810360008301526153498161530d565b905091905056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bbf06b6163a3b4bfa17cb8d84cf98632ab690d1effb7062541e386cf055d830064736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
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.