Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Ownersh... | 30201155 | 245 days ago | IN | 0 ETH | 0.00000022 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TierAttestationAttester
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 800 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// contracts/TierAttestationAttester.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import {
IEAS,
AttestationRequest,
MultiAttestationRequest,
RevocationRequest,
MultiRevocationRequest
} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import {InvalidEAS} from "@ethereum-attestation-service/eas-contracts/contracts/Common.sol";
import {AOwnableInitializableContract} from "./abstracts/AOwnableInitializableContract.sol";
import {ITierAttestationAttester} from "./interfaces/ITierAttestationAttester.sol";
/**
* @title TierAttestationAttester
* @author Geoffrey Garcia
* @notice Contract to request for AES attestations.
* @dev This contract interacts with the global EAS contract.
*/
contract TierAttestationAttester is ITierAttestationAttester, AOwnableInitializableContract {
// Storage of the resolver
mapping(address => bool) internal _verifierAddresses; // The allow-list of verifier contracts.
IEAS internal _eas; // The instance of the EAS contract.
/**
* @notice Constructor of the contract.
* @dev See {AOwnableInitializableContract-constructor}.
* @param easAddress The address of the global EAS contract.
*/
constructor(address easAddress) {
initAttester(easAddress);
}
/**
* @dev See {ITierAttestationResolver-setEAS}.
*/
function setEAS(address easAddress) external override onlyOwner {
_setEAS(easAddress);
}
/**
* @dev See {ITierAttestationAttester-addVerifier}.
*/
function addVerifier(address verifierAddress) public override onlyOwner {
// Checking if the verifier is not already allowed
if(_verifierAddresses[verifierAddress]) {
revert VerifierAlreadyAdded(verifierAddress);
}
_verifierAddresses[verifierAddress] = true;
emit ModifyVerifier(verifierAddress, true);
}
/**
* @dev See {ITierAttestationAttester-removeVerifier}.
*/
function removeVerifier(address verifierAddress) public override onlyOwner {
// Checking if the verifier is previously allowed
if(!_verifierAddresses[verifierAddress]) {
revert UnknownVerifier(verifierAddress);
}
_verifierAddresses[verifierAddress] = false;
emit ModifyVerifier(verifierAddress, false);
}
/**
* @dev See {ITierAttestationAttester-submitAttestation}.
*/
function submitAttestation(
AttestationRequest calldata attestationRequest
) public payable override returns (bytes32 uID) {
_requireAuthorizedVerifier(_msgSender());
return _eas.attest{ value: msg.value }(attestationRequest);
}
/**
* @dev See {ITierAttestationAttester-revokeAttestation}.
*/
function revokeAttestation(
RevocationRequest calldata revocationRequest
) public payable override {
_requireAuthorizedVerifier(_msgSender());
_eas.revoke{ value: msg.value }(revocationRequest);
}
/**
* @dev See {ITierAttestationAttester-submitAttestations}.
*/
function submitAttestations(
MultiAttestationRequest calldata multiAttestationRequest
) public payable override returns (bytes32[] memory uIDs) {
_requireAuthorizedVerifier(_msgSender());
MultiAttestationRequest[] memory multiRequests = new MultiAttestationRequest[](1);
multiRequests[0] = multiAttestationRequest;
return _eas.multiAttest{ value: msg.value }(multiRequests);
}
/**
* @dev See {ITierAttestationAttester-revokeAttestations}.
*/
function revokeAttestations(
MultiRevocationRequest calldata multiRevocationRequest
) public payable override {
_requireAuthorizedVerifier(_msgSender());
MultiRevocationRequest[] memory multiRequests = new MultiRevocationRequest[](1);
multiRequests[0] = multiRevocationRequest;
_eas.multiRevoke{ value: msg.value }(multiRequests);
}
/**
* @dev See {ITierAttestationAttester-initAttester}.
*/
function initAttester(address easAddress) public override initializer {
_setEAS(easAddress);
}
/**
* @notice Internal function to update the global EAS contract.
* @dev Emit the ModifyEAS event if it succeeds.
* @param easAddress The address of the global EAS contract.
*/
function _setEAS(address easAddress) internal {
if (easAddress == address(0)) {
revert InvalidEAS();
}
_eas = IEAS(easAddress);
emit ModifyEAS(easAddress);
}
/**
* @notice Evaluate if the verifier is authorized.
* @dev If the constraints are not met the transaction will be reverted.
* @param verifierAddress The supposed address of the verifier.
*/
function _requireAuthorizedVerifier(address verifierAddress) internal view {
// Checking if the verifier is allowed
if(!_verifierAddresses[verifierAddress]) {
revert UnauthorizedVerifier(verifierAddress);
}
}
}// 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 { ISemver } from "./ISemver.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 is ISemver {
/// @notice Emitted when an attestation has been made.
/// @param recipient The recipient of the attestation.
/// @param attester The attesting account.
/// @param uid The UID of the new 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 { ISemver } from "./ISemver.sol";
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 is ISemver {
/// @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;
/// @title ISemver
/// @notice A semver interface.
interface ISemver {
/// @notice Returns the full semver contract version.
/// @return Semver contract version as a string.
function version() external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Attestation } from "./../Common.sol";
import { ISemver } from "./../ISemver.sol";
/// @title ISchemaResolver
/// @notice The interface of an optional schema resolver.
interface ISchemaResolver is ISemver {
/// @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 v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.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.
*
* The initial owner is set to the address provided by the deployer. 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 Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @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 Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reinitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._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 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._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() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @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 {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
*
* NOTE: Consider following the ERC-7201 formula to derive storage locations.
*/
function _initializableStorageSlot() internal pure virtual returns (bytes32) {
return INITIALIZABLE_STORAGE;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
bytes32 slot = _initializableStorageSlot();
assembly {
$.slot := slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// contracts/abstracts/AOwnableInitializableContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/**
* @title AOwnableInitializableContract
* @author Geoffrey Garcia
* @notice Abstract contract to implement in order to create ownable and initializable contracts.
* @dev The AOwnableInitializableContract contract provides only a constructor.
*/
abstract contract AOwnableInitializableContract is Ownable, Initializable {
/**
* @notice Instanciate the contract.
* @dev See {Initializable-constructor} and {Ownable-constructor}.
*/
constructor() Ownable(_msgSender()) {
}
}// contracts/interfaces/ITierAttestationAttester.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import {
AttestationRequest,
MultiAttestationRequest,
RevocationRequest,
MultiRevocationRequest
} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
/**
* @title ITierAttestationAttester
* @author Geoffrey Garcia
* @notice Interface to request for AES attestations.
* @dev This contract interacts with the global EAS contract.
*/
interface ITierAttestationAttester {
/**
* @notice Event emitted when the global EAS contract is set.
* @dev Event emitted at instanciation and when the owner changes it.
* @param eas The address of the global EAS contract.
*/
event ModifyEAS(address eas);
/**
* @notice Event emitted when a verifier is moved in/out the allow-list.
* @dev Event emitted when the owner changes it.
* @param verifier The address of the verifier contract.
* @param status The status of the verifier (true -> approved; false -> refused).
*/
event ModifyVerifier(address verifier, bool status);
/**
* @notice Error emitted when an already allowed verifier is attempted to be allowed again.
* @param verifier The already allowed address of the verifier contract.
*/
error VerifierAlreadyAdded(address verifier);
/**
* @notice Error emitted when an unknown verifier is attempted to be unallowed.
* @param verifier The unknown address of the potential verifier contract.
*/
error UnknownVerifier(address verifier);
/**
* @notice Error emitted when verifier-restricted functions are attempted to be called by an unallowed address.
* @param verifier The unallowed address of the potential verifier contract.
*/
error UnauthorizedVerifier(address verifier);
/**
* @notice Initialize the attester contract.
* @dev Such initialization can be triggered by the constructor or a proxy.
* @param easAddress The address of the global EAS contract.
*/
function initAttester(address easAddress) external;
/**
* @notice Function to update the global EAS contract.
* @dev Sets the address of the EAS contract.
* @param easAddress The address of the global EAS contract.
*/
function setEAS(address easAddress) external;
/**
* @notice Function to add an authorized attester.
* @dev Adds a verifier to the allow-list.
* @param verifierAddress The address of the verifier to add.
*/
function addVerifier(address verifierAddress) external;
/**
* @notice Function to remove an authorized attester.
* @dev Removes a verifier from the allow-list.
* @param verifierAddress The address of the verifier to remove.
*/
function removeVerifier(address verifierAddress) external;
/**
* @notice Function to submit attestation.
* @dev Adds EtherScore's tier related information for the user.
* @param attestationRequest The structures containing the information of the attestation.
* @return uID The UID of the new attestation.
*/
function submitAttestation(
AttestationRequest calldata attestationRequest
) external payable returns (bytes32 uID);
/**
* @notice Function to revoke attestation.
* @dev Revoke attestation by schema and uid
* @param revocationRequest The structures containing the attestation to revoke.
*/
function revokeAttestation(
RevocationRequest calldata revocationRequest
) external payable;
/**
* @notice Function to submit several attestations.
* @dev Adds EtherScore's tiers related information for the users.
* @param multiAttestationRequest The structures containing the information of the attestations.
* @return uIDs The UIDs of the new attestations.
*/
function submitAttestations(
MultiAttestationRequest calldata multiAttestationRequest
) external payable returns (bytes32[] memory uIDs);
/**
* @notice Function to revoke several attestations.
* @dev Revoke attestations by schema and uids
* @param multiRevocationRequest The structures containing the attestations to revoke.
*/
function revokeAttestations(
MultiRevocationRequest calldata multiRevocationRequest
) external payable;
}{
"viaIR": true,
"optimizer": {
"enabled": true,
"runs": 800,
"details": {
"deduplicate": true,
"yul": true
}
},
"evmVersion": "paris",
"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":"address","name":"easAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidEAS","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"verifier","type":"address"}],"name":"UnauthorizedVerifier","type":"error"},{"inputs":[{"internalType":"address","name":"verifier","type":"address"}],"name":"UnknownVerifier","type":"error"},{"inputs":[{"internalType":"address","name":"verifier","type":"address"}],"name":"VerifierAlreadyAdded","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"eas","type":"address"}],"name":"ModifyEAS","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"verifier","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ModifyVerifier","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"},{"inputs":[{"internalType":"address","name":"verifierAddress","type":"address"}],"name":"addVerifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"easAddress","type":"address"}],"name":"initAttester","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"verifierAddress","type":"address"}],"name":"removeVerifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"schema","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct RevocationRequestData","name":"data","type":"tuple"}],"internalType":"struct RevocationRequest","name":"revocationRequest","type":"tuple"}],"name":"revokeAttestation","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"schema","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct RevocationRequestData[]","name":"data","type":"tuple[]"}],"internalType":"struct MultiRevocationRequest","name":"multiRevocationRequest","type":"tuple"}],"name":"revokeAttestations","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"easAddress","type":"address"}],"name":"setEAS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"schema","type":"bytes32"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AttestationRequestData","name":"data","type":"tuple"}],"internalType":"struct AttestationRequest","name":"attestationRequest","type":"tuple"}],"name":"submitAttestation","outputs":[{"internalType":"bytes32","name":"uID","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"schema","type":"bytes32"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AttestationRequestData[]","name":"data","type":"tuple[]"}],"internalType":"struct MultiAttestationRequest","name":"multiAttestationRequest","type":"tuple"}],"name":"submitAttestations","outputs":[{"internalType":"bytes32[]","name":"uIDs","type":"bytes32[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60803461023757601f61123638819003918201601f19168301916001600160401b0383118484101761023c5780849260209460405283398101031261023757516001600160a01b038116908190036102375733156102215760008054336001600160a01b03198216811783556040519290916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360008051602061121683398151915254604081901c60ff161592906001600160401b03811680159081610219575b600114908161020f575b159081610206575b506101f5576001600160401b0319811660011760008051602061121683398151915255836101ca575b5080156101b957600280546001600160a01b0319168217905581527f09a4edf4aa4de7906cb6dcc775ced07807d94f7530748dc966d27688f57fa0f890602090a161015d575b604051610fc390816102538239f35b68ff0000000000000000196000805160206112168339815191525416600080516020611216833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a161014e565b6341bc07ff60e11b60005260046000fd5b6001600160481b03191668010000000000000001176000805160206112168339815191525538610108565b63f92ee8a960e01b60005260046000fd5b905015386100df565b303b1591506100d7565b8591506100cd565b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe60c080604052600436101561001357600080fd5b600060a05260a0513560e01c9081630b63056414610c16575080632398f32814610ab0578063382eb53314610638578063715018a6146105d95780638da5cb5b146105b05780639000b3d614610507578063ae8503d7146102f4578063b2f6a6d714610263578063ca2dfd0a146101bb578063d2cae4a0146101355763f2fde38b1461009e57600080fd5b3461012f57602036600319011261012f576001600160a01b036100bf610dff565b6100c7610f64565b1680156101165760a05180546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360a05180f35b631e4fbdf760e01b60a0515260a051600452602460a051fd5b60a05180fd5b3461012f57602036600319011261012f576001600160a01b03610156610dff565b61015e610f64565b1680156101a8576020817f09a4edf4aa4de7906cb6dcc775ced07807d94f7530748dc966d27688f57fa0f8926001600160a01b03196002541617600255604051908152a160a05180f35b6341bc07ff60e11b60a05152600460a051fd5b3461012f57602036600319011261012f576001600160a01b036101dc610dff565b6101e4610f64565b168060a05152600160205260ff604060a0512054161561024d576040817f9d04ce4e706a951f752ee9fc3bc7ad4f0da679b1835cbb17c3b61ebaa5eedbfb9260a0515260016020528160a0512060ff198154169055815190815260a0516020820152a160a05180f35b6372a161ab60e01b60a05152600452602460a051fd5b606036600319011261012f5761027833610f2d565b6001600160a01b0360025416803b1561012f5760405190634692626760e01b82526004356004830152602435602483015260443560448301528160648160a0519334905af180156102e7576102ce575b60a05180f35b60a0516102da91610e94565b60a05161012f57806102c8565b6040513d60a051823e3d90fd5b6102fd36610e2e565b61030633610f2d565b60408051916103158284610e94565b60018352601f19820160a0515b8181106104f0575050818136031261012f5781519061034082610e62565b8035825260208101359067ffffffffffffffff821161012f570136601f8201121561012f5780359061037182610ed8565b9161037e85519384610e94565b80835260208084019160061b8301019136831161012f57602001905b8282106104c15750505060208201526103b283610f0a565b526103bc82610f0a565b506001600160a01b036002541691823b1561012f5781518093634cb7e9e560e01b8252602482016020600484015283518091526044830190602060448260051b86010195019160a051905b82821061044d5750505050818060a05194039134905af190811561044257506104305760a05180f35b60a05161043c91610e94565b806102c8565b513d60a051823e3d90fd5b919394509194604319888203018252855160206060818a850193805186520151938a8382015284518094520192019060a0515b898282106104a257505050506020806001929701920192018794939192610407565b8351805186526020908101518187015294019390920191600101610480565b858236031261012f576020869182516104d981610e62565b84358152828501358382015281520191019061039a565b6020906104fb610ef0565b82828801015201610322565b3461012f57602036600319011261012f576001600160a01b03610528610dff565b610530610f64565b168060a05152600160205260ff604060a05120541661059a576040817f9d04ce4e706a951f752ee9fc3bc7ad4f0da679b1835cbb17c3b61ebaa5eedbfb9260a0515260016020528160a05120600160ff19825416179055815190815260016020820152a160a05180f35b631594e79960e31b60a05152600452602460a051fd5b3461012f5760a05136600319011261012f5760206001600160a01b0360a0515416604051908152f35b3461012f5760a05136600319011261012f576105f3610f64565b60a05180546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a360a05180f35b61064136610e2e565b61064a33610f2d565b60408051909161065a8383610e94565b60018252601f19830160a0515b818110610a99575050828136031261012f5782519061068582610e62565b8035825260208101359067ffffffffffffffff821161012f570136601f8201121561012f5780356106b581610ed8565b916106c286519384610e94565b81835260208084019260051b8201019036821161012f5760208101925b82841061097e575050505060208201526106f882610f0a565b5261070281610f0a565b506001600160a01b0360025416908251608052632256e48760e11b60805152602460805101602060046080510152815180915260446080510190602060448260051b608051010193019160a051905b82821061086c575050505060a05191608051916080519003906080519034905af180156108605760a051906107c5575b9080519182916020808401918185528351809352840192019060a0515b8181106107ac575050500390f35b825184528594506020938401939092019160010161079e565b503d8060a0516080513e6107db81608051610e94565b60805101602060805182031261012f576080515167ffffffffffffffff811161012f57608051019080601f8301121561012f57815161081981610ed8565b9261082685519485610e94565b81845260208085019260051b82010192831161012f57602001905b82821061085057505050610781565b8151815260209182019101610841565b50513d60a051823e3d90fd5b9091929360431960805182030182528451906020888201928051835201519188602083015282518091526060820190602060608260051b85010194019260a0515b8281106108cd575050505050602080600192960192019201909291610751565b9091929394605f1983820301855285516001600160a01b03815116825267ffffffffffffffff60208201511660208301528c81015115158d8301526060810151606083015260808101519060c060808401528151918260c085015260a0515b83811061096857505060e060019360209360a085948151858486010152015160a0830152601f80199101160101970195019101929190926108ad565b80602080928401015160e082880101520161092c565b833567ffffffffffffffff811161012f5782019060c0601f19833603011261012f5788519060c0820182811067ffffffffffffffff821117610a81578a526109c860208401610e1a565b82526109d58a8401610eb6565b60208301526109e660608401610ecb565b8a8301526080830135606083015260a083013567ffffffffffffffff811161012f576020908401019136601f8401121561012f5782359267ffffffffffffffff8411610a81578b5194610a43601f8601601f191660200187610e94565b848652366020868401011161012f576020958587968760c09501888401378660a05191830101526080840152013560a08201528152019301926106df565b634e487b7160e01b60a051526041600452602460a051fd5b602090610aa4610ef0565b82828701015201610667565b610ab936610e2e565b610ac233610f2d565b6001600160a01b03600254166040519163f17325e760e01b83526020600484015280356024840152602081013560be198236030181121561012f5701604060448401526001600160a01b03610b1682610e1a565b16606484015267ffffffffffffffff610b3160208301610eb6565b166084840152610b4360408201610ecb565b151560a4840152606081013560c48401526080810135601e198236030181121561012f578101916020833593019267ffffffffffffffff811161012f57803603841361012f57610144858260a08296839560209960c060e4870152816101248701528686013781518484018601520135610104830152601f01601f1916810103019134905af180156102e75760a05190610be3575b602090604051908152f35b506020813d602011610c0e575b81610bfd60209383610e94565b8101031261012f5760209051610bd8565b3d9150610bf0565b3461012f57602036600319011261012f57610c2f610dff565b907ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c16159267ffffffffffffffff821680159081610df7575b6001149081610ded575b159081610de4575b50610dd15767ffffffffffffffff1982166001177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00556001600160a01b039184610d92575b501680156101a8577f09a4edf4aa4de7906cb6dcc775ced07807d94f7530748dc966d27688f57fa0f891816020926001600160a01b031960025416176002558152a1610d125760a05180f35b68ff0000000000000000197ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054167ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a16102c8565b68ffffffffffffffffff191668010000000000000001177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005584610cc6565b63f92ee8a960e01b60a05152600460a051fd5b90501585610c81565b303b159150610c79565b859150610c6f565b600435906001600160a01b0382168203610e1557565b600080fd5b35906001600160a01b0382168203610e1557565b6020600319820112610e15576004359067ffffffffffffffff8211610e15576040908290036003190112610e155760040190565b6040810190811067ffffffffffffffff821117610e7e57604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610e7e57604052565b359067ffffffffffffffff82168203610e1557565b35908115158203610e1557565b67ffffffffffffffff8111610e7e5760051b60200190565b60405190610efd82610e62565b6060602083600081520152565b805115610f175760200190565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b031680600052600160205260ff6040600020541615610f505750565b631eb1c0a560e01b60005260045260246000fd5b6001600160a01b03600054163303610f7857565b63118cdaa760e01b6000523360045260246000fdfea264697066735822122094af84d770e705819d3092b2f8f3705cb2aa5aed86f5c957b61e2ffedc7bfaf364736f6c634300081c0033f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a000000000000000000000000004200000000000000000000000000000000000021
Deployed Bytecode
0x60c080604052600436101561001357600080fd5b600060a05260a0513560e01c9081630b63056414610c16575080632398f32814610ab0578063382eb53314610638578063715018a6146105d95780638da5cb5b146105b05780639000b3d614610507578063ae8503d7146102f4578063b2f6a6d714610263578063ca2dfd0a146101bb578063d2cae4a0146101355763f2fde38b1461009e57600080fd5b3461012f57602036600319011261012f576001600160a01b036100bf610dff565b6100c7610f64565b1680156101165760a05180546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360a05180f35b631e4fbdf760e01b60a0515260a051600452602460a051fd5b60a05180fd5b3461012f57602036600319011261012f576001600160a01b03610156610dff565b61015e610f64565b1680156101a8576020817f09a4edf4aa4de7906cb6dcc775ced07807d94f7530748dc966d27688f57fa0f8926001600160a01b03196002541617600255604051908152a160a05180f35b6341bc07ff60e11b60a05152600460a051fd5b3461012f57602036600319011261012f576001600160a01b036101dc610dff565b6101e4610f64565b168060a05152600160205260ff604060a0512054161561024d576040817f9d04ce4e706a951f752ee9fc3bc7ad4f0da679b1835cbb17c3b61ebaa5eedbfb9260a0515260016020528160a0512060ff198154169055815190815260a0516020820152a160a05180f35b6372a161ab60e01b60a05152600452602460a051fd5b606036600319011261012f5761027833610f2d565b6001600160a01b0360025416803b1561012f5760405190634692626760e01b82526004356004830152602435602483015260443560448301528160648160a0519334905af180156102e7576102ce575b60a05180f35b60a0516102da91610e94565b60a05161012f57806102c8565b6040513d60a051823e3d90fd5b6102fd36610e2e565b61030633610f2d565b60408051916103158284610e94565b60018352601f19820160a0515b8181106104f0575050818136031261012f5781519061034082610e62565b8035825260208101359067ffffffffffffffff821161012f570136601f8201121561012f5780359061037182610ed8565b9161037e85519384610e94565b80835260208084019160061b8301019136831161012f57602001905b8282106104c15750505060208201526103b283610f0a565b526103bc82610f0a565b506001600160a01b036002541691823b1561012f5781518093634cb7e9e560e01b8252602482016020600484015283518091526044830190602060448260051b86010195019160a051905b82821061044d5750505050818060a05194039134905af190811561044257506104305760a05180f35b60a05161043c91610e94565b806102c8565b513d60a051823e3d90fd5b919394509194604319888203018252855160206060818a850193805186520151938a8382015284518094520192019060a0515b898282106104a257505050506020806001929701920192018794939192610407565b8351805186526020908101518187015294019390920191600101610480565b858236031261012f576020869182516104d981610e62565b84358152828501358382015281520191019061039a565b6020906104fb610ef0565b82828801015201610322565b3461012f57602036600319011261012f576001600160a01b03610528610dff565b610530610f64565b168060a05152600160205260ff604060a05120541661059a576040817f9d04ce4e706a951f752ee9fc3bc7ad4f0da679b1835cbb17c3b61ebaa5eedbfb9260a0515260016020528160a05120600160ff19825416179055815190815260016020820152a160a05180f35b631594e79960e31b60a05152600452602460a051fd5b3461012f5760a05136600319011261012f5760206001600160a01b0360a0515416604051908152f35b3461012f5760a05136600319011261012f576105f3610f64565b60a05180546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a360a05180f35b61064136610e2e565b61064a33610f2d565b60408051909161065a8383610e94565b60018252601f19830160a0515b818110610a99575050828136031261012f5782519061068582610e62565b8035825260208101359067ffffffffffffffff821161012f570136601f8201121561012f5780356106b581610ed8565b916106c286519384610e94565b81835260208084019260051b8201019036821161012f5760208101925b82841061097e575050505060208201526106f882610f0a565b5261070281610f0a565b506001600160a01b0360025416908251608052632256e48760e11b60805152602460805101602060046080510152815180915260446080510190602060448260051b608051010193019160a051905b82821061086c575050505060a05191608051916080519003906080519034905af180156108605760a051906107c5575b9080519182916020808401918185528351809352840192019060a0515b8181106107ac575050500390f35b825184528594506020938401939092019160010161079e565b503d8060a0516080513e6107db81608051610e94565b60805101602060805182031261012f576080515167ffffffffffffffff811161012f57608051019080601f8301121561012f57815161081981610ed8565b9261082685519485610e94565b81845260208085019260051b82010192831161012f57602001905b82821061085057505050610781565b8151815260209182019101610841565b50513d60a051823e3d90fd5b9091929360431960805182030182528451906020888201928051835201519188602083015282518091526060820190602060608260051b85010194019260a0515b8281106108cd575050505050602080600192960192019201909291610751565b9091929394605f1983820301855285516001600160a01b03815116825267ffffffffffffffff60208201511660208301528c81015115158d8301526060810151606083015260808101519060c060808401528151918260c085015260a0515b83811061096857505060e060019360209360a085948151858486010152015160a0830152601f80199101160101970195019101929190926108ad565b80602080928401015160e082880101520161092c565b833567ffffffffffffffff811161012f5782019060c0601f19833603011261012f5788519060c0820182811067ffffffffffffffff821117610a81578a526109c860208401610e1a565b82526109d58a8401610eb6565b60208301526109e660608401610ecb565b8a8301526080830135606083015260a083013567ffffffffffffffff811161012f576020908401019136601f8401121561012f5782359267ffffffffffffffff8411610a81578b5194610a43601f8601601f191660200187610e94565b848652366020868401011161012f576020958587968760c09501888401378660a05191830101526080840152013560a08201528152019301926106df565b634e487b7160e01b60a051526041600452602460a051fd5b602090610aa4610ef0565b82828701015201610667565b610ab936610e2e565b610ac233610f2d565b6001600160a01b03600254166040519163f17325e760e01b83526020600484015280356024840152602081013560be198236030181121561012f5701604060448401526001600160a01b03610b1682610e1a565b16606484015267ffffffffffffffff610b3160208301610eb6565b166084840152610b4360408201610ecb565b151560a4840152606081013560c48401526080810135601e198236030181121561012f578101916020833593019267ffffffffffffffff811161012f57803603841361012f57610144858260a08296839560209960c060e4870152816101248701528686013781518484018601520135610104830152601f01601f1916810103019134905af180156102e75760a05190610be3575b602090604051908152f35b506020813d602011610c0e575b81610bfd60209383610e94565b8101031261012f5760209051610bd8565b3d9150610bf0565b3461012f57602036600319011261012f57610c2f610dff565b907ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c16159267ffffffffffffffff821680159081610df7575b6001149081610ded575b159081610de4575b50610dd15767ffffffffffffffff1982166001177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00556001600160a01b039184610d92575b501680156101a8577f09a4edf4aa4de7906cb6dcc775ced07807d94f7530748dc966d27688f57fa0f891816020926001600160a01b031960025416176002558152a1610d125760a05180f35b68ff0000000000000000197ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054167ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a16102c8565b68ffffffffffffffffff191668010000000000000001177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005584610cc6565b63f92ee8a960e01b60a05152600460a051fd5b90501585610c81565b303b159150610c79565b859150610c6f565b600435906001600160a01b0382168203610e1557565b600080fd5b35906001600160a01b0382168203610e1557565b6020600319820112610e15576004359067ffffffffffffffff8211610e15576040908290036003190112610e155760040190565b6040810190811067ffffffffffffffff821117610e7e57604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610e7e57604052565b359067ffffffffffffffff82168203610e1557565b35908115158203610e1557565b67ffffffffffffffff8111610e7e5760051b60200190565b60405190610efd82610e62565b6060602083600081520152565b805115610f175760200190565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b031680600052600160205260ff6040600020541615610f505750565b631eb1c0a560e01b60005260045260246000fd5b6001600160a01b03600054163303610f7857565b63118cdaa760e01b6000523360045260246000fdfea264697066735822122094af84d770e705819d3092b2f8f3705cb2aa5aed86f5c957b61e2ffedc7bfaf364736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004200000000000000000000000000000000000021
-----Decoded View---------------
Arg [0] : easAddress (address): 0x4200000000000000000000000000000000000021
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000004200000000000000000000000000000000000021
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.