Source Code
Overview
ETH Balance
ETH Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Toggle Attester | 8174160 | 542 days ago | IN | 0 ETH | 0.00000283 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ToasterBadge
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-3.0
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ScrollBadge} from "./canvas-contracts/src/badge/ScrollBadge.sol";
import {ScrollBadgeAccessControl} from "./canvas-contracts/src/badge/extensions/ScrollBadgeAccessControl.sol";
import {ScrollBadgeSingleton} from "./canvas-contracts/src/badge/extensions/ScrollBadgeSingleton.sol";
function decodePayloadData(bytes memory data) pure returns (uint8) {
return abi.decode(data, (uint8));
}
/// @title ToasterBadge
/// @notice This contract implements the Toaster scroll badge.
/// @author danny <[email protected]>
contract ToasterBadge is ScrollBadgeAccessControl, ScrollBadgeSingleton {
string public baseTokenURI;
uint8 public immutable variant;
constructor(
address resolver_,
uint8 variant_,
string memory _baseTokenURI
) ScrollBadge(resolver_) Ownable() {
variant = variant_;
baseTokenURI = _baseTokenURI;
}
/// @inheritdoc ScrollBadge
function onIssueBadge(
Attestation calldata attestation
)
internal
override(ScrollBadgeAccessControl, ScrollBadgeSingleton)
returns (bool)
{
return super.onIssueBadge(attestation);
}
/// @inheritdoc ScrollBadge
function onRevokeBadge(
Attestation calldata attestation
)
internal
override(ScrollBadgeAccessControl, ScrollBadgeSingleton)
returns (bool)
{
return super.onRevokeBadge(attestation);
}
/// @inheritdoc ScrollBadge
function badgeTokenURI(
bytes32 /*uid*/
) public view override returns (string memory) {
return
string(
abi.encodePacked(
baseTokenURI,
Strings.toString(variant),
".json"
)
);
}
function setBaseTokenURI(string memory _baseTokenURI) public onlyOwner {
baseTokenURI = _baseTokenURI;
}
}// 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 { ISemver } from "../ISemver.sol";
import { Attestation } from "../Common.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 v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../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.
*
* 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 Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.6) (utils/Base64.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides a set of functions to operate with Base64 strings.
*
* _Available since v4.5._
*/
library Base64 {
/**
* @dev Base64 Encoding/Decoding Table
*/
string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* @dev Converts a `bytes` to its Bytes64 `string` representation.
*/
function encode(bytes memory data) internal pure returns (string memory) {
/**
* Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
* https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
*/
if (data.length == 0) return "";
// Loads the table into memory
string memory table = _TABLE;
// Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
// and split into 4 numbers of 6 bits.
// The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
// - `data.length + 2` -> Round up
// - `/ 3` -> Number of 3-bytes chunks
// - `4 *` -> 4 characters for each chunk
string memory result = new string(4 * ((data.length + 2) / 3));
/// @solidity memory-safe-assembly
assembly {
// Prepare the lookup table (skip the first "length" byte)
let tablePtr := add(table, 1)
// Prepare result pointer, jump over length
let resultPtr := add(result, 0x20)
let dataPtr := data
let endPtr := add(data, mload(data))
// In some cases, the last iteration will read bytes after the end of the data. We cache the value, and
// set it to zero to make sure no dirty bytes are read in that section.
let afterPtr := add(endPtr, 0x20)
let afterCache := mload(afterPtr)
mstore(afterPtr, 0x00)
// Run over the input, 3 bytes at a time
for {
} lt(dataPtr, endPtr) {
} {
// Advance 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
// To write each character, shift the 3 byte (24 bits) chunk
// 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
// and apply logical AND with 0x3F to bitmask the least significant 6 bits.
// Use this as an index into the lookup table, mload an entire word
// so the desired character is in the least significant byte, and
// mstore8 this least significant byte into the result and continue.
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
}
// Reset the value that was cached
mstore(afterPtr, afterCache)
// When data `bytes` is not exactly 3 bytes long
// it is padded with `=` characters at the end
switch mod(mload(data), 3)
case 1 {
mstore8(sub(resultPtr, 1), 0x3d)
mstore8(sub(resultPtr, 2), 0x3d)
}
case 2 {
mstore8(sub(resultPtr, 1), 0x3d)
}
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ScrollBadge} from "../ScrollBadge.sol";
import {Unauthorized} from "../../Errors.sol";
/// @title ScrollBadgeAccessControl
/// @notice This contract adds access control to ScrollBadge.
/// @dev In EAS, only the original attester can revoke an attestation. If the original
// attester was removed and a new was added in this contract, it will not be able
// to revoke previous attestations.
abstract contract ScrollBadgeAccessControl is Ownable, ScrollBadge {
// Authorized badge issuer and revoker accounts.
mapping(address => bool) public isAttester;
/// @notice Enables or disables a given attester.
/// @param attester The attester address.
/// @param enable True if enable, false if disable.
function toggleAttester(address attester, bool enable) external onlyOwner {
isAttester[attester] = enable;
}
/// @inheritdoc ScrollBadge
function onIssueBadge(Attestation calldata attestation) internal virtual override returns (bool) {
if (!super.onIssueBadge(attestation)) {
return false;
}
// only allow authorized issuers
if (!isAttester[attestation.attester]) {
revert Unauthorized();
}
return true;
}
/// @inheritdoc ScrollBadge
function onRevokeBadge(Attestation calldata attestation) internal virtual override returns (bool) {
if (!super.onRevokeBadge(attestation)) {
return false;
}
// only allow authorized revokers
if (!isAttester[attestation.attester]) {
revert Unauthorized();
}
return true;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import {ScrollBadge} from "../ScrollBadge.sol";
import {SingletonBadge} from "../../Errors.sol";
/// @title ScrollBadgeSingleton
/// @notice This contract only allows one active badge per wallet.
abstract contract ScrollBadgeSingleton is ScrollBadge {
/// @inheritdoc ScrollBadge
function onIssueBadge(Attestation calldata attestation) internal virtual override returns (bool) {
if (!super.onIssueBadge(attestation)) {
return false;
}
if (hasBadge(attestation.recipient)) {
revert SingletonBadge();
}
return true;
}
/// @inheritdoc ScrollBadge
function onRevokeBadge(Attestation calldata attestation) internal virtual override returns (bool) {
return super.onRevokeBadge(attestation);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import {decodeBadgeData} from "../Common.sol";
import {IScrollBadge} from "../interfaces/IScrollBadge.sol";
import {IScrollBadgeResolver} from "../interfaces/IScrollBadgeResolver.sol";
import {AttestationBadgeMismatch, Unauthorized} from "../Errors.sol";
/// @title ScrollBadge
/// @notice This contract implements the basic functionalities of a Scroll badge.
/// It serves as the base contract for more complex badge functionalities.
abstract contract ScrollBadge is IScrollBadge {
// The global Scroll badge resolver contract.
address public immutable resolver;
// wallet address => badge count
mapping(address => uint256) private _userBadgeCount;
/// @dev Creates a new ScrollBadge instance.
/// @param resolver_ The address of the global Scroll badge resolver contract.
constructor(address resolver_) {
resolver = resolver_;
}
/// @inheritdoc IScrollBadge
function issueBadge(Attestation calldata attestation) public returns (bool) {
// only callable from resolver
if (msg.sender != address(resolver)) {
revert Unauthorized();
}
// delegate logic to subcontract
if (!onIssueBadge(attestation)) {
return false;
}
_userBadgeCount[attestation.recipient] += 1;
emit IssueBadge(attestation.uid);
return true;
}
/// @inheritdoc IScrollBadge
function revokeBadge(Attestation calldata attestation) public returns (bool) {
// only callable from resolver
if (msg.sender != address(resolver)) {
revert Unauthorized();
}
// delegate logic to subcontract
if (!onRevokeBadge(attestation)) {
return false;
}
_userBadgeCount[attestation.recipient] -= 1;
emit RevokeBadge(attestation.uid);
return true;
}
/// @notice A resolver callback that should be implemented by child contracts.
/// @param {attestation} The new attestation.
/// @return Whether the attestation is valid.
function onIssueBadge(Attestation calldata /*attestation*/ ) internal virtual returns (bool) {
return true;
}
/// @notice A resolver callback that should be implemented by child contracts.
/// @param {attestation} The existing attestation to be revoked.
/// @return Whether the attestation can be revoked.
function onRevokeBadge(Attestation calldata /*attestation*/ ) internal virtual returns (bool) {
return true;
}
/// @inheritdoc IScrollBadge
function getAndValidateBadge(bytes32 uid) public view returns (Attestation memory) {
Attestation memory attestation = IScrollBadgeResolver(resolver).getAndValidateBadge(uid);
(address badge,) = decodeBadgeData(attestation.data);
if (badge != address(this)) {
revert AttestationBadgeMismatch(uid);
}
return attestation;
}
/// @inheritdoc IScrollBadge
function badgeTokenURI(bytes32 uid) public view virtual returns (string memory);
/// @inheritdoc IScrollBadge
function hasBadge(address user) public view virtual returns (bool) {
return _userBadgeCount[user] > 0;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
uint256 constant MAX_ATTACHED_BADGE_NUM = 48;
string constant SCROLL_BADGE_SCHEMA = "address badge, bytes payload";
function decodeBadgeData(bytes memory data) pure returns (address, bytes memory) {
return abi.decode(data, (address, bytes));
}// SPDX-License-Identifier: MIT pragma solidity 0.8.19; error Unauthorized(); error CannotUpgrade(bytes32 uid); // attestation errors // note: these don't include the uid since it is not known prior to the attestation. error BadgeNotAllowed(address badge); error BadgeNotFound(address badge); error ExpirationDisabled(); error MissingPayload(); error ResolverPaymentsDisabled(); error RevocationDisabled(); error SingletonBadge(); error UnknownSchema(); // query errors error AttestationBadgeMismatch(bytes32 uid); error AttestationExpired(bytes32 uid); error AttestationNotFound(bytes32 uid); error AttestationOwnerMismatch(bytes32 uid); error AttestationRevoked(bytes32 uid); error AttestationSchemaMismatch(bytes32 uid); // profile errors error BadgeCountReached(); error LengthMismatch(); error TokenNotOwnedByUser(address token, uint256 tokenId); // profile registry errors error CallerIsNotUserProfile(); error DuplicatedUsername(); error ExpiredSignature(); error ImplementationNotContract(); error InvalidReferrer(); error InvalidSignature(); error InvalidUsername(); error MsgValueMismatchWithMintFee(); error ProfileAlreadyMinted();
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
interface IScrollBadge {
event IssueBadge(bytes32 indexed uid);
event RevokeBadge(bytes32 indexed uid);
/// @notice A resolver callback invoked in the `issueBadge` function in the parent contract.
/// @param attestation The new attestation.
/// @return Whether the attestation is valid.
function issueBadge(Attestation calldata attestation) external returns (bool);
/// @notice A resolver callback invoked in the `revokeBadge` function in the parent contract.
/// @param attestation The new attestation.
/// @return Whether the attestation can be revoked.
function revokeBadge(Attestation calldata attestation) external returns (bool);
/// @notice Validate and return a Scroll badge attestation.
/// @param uid The attestation UID.
/// @return The attestation.
function getAndValidateBadge(bytes32 uid) external view returns (Attestation memory);
/// @notice Returns the token URI corresponding to a certain badge UID, or the default
/// badge token URI if the pass UID is 0x0.
/// @param uid The badge UID, or 0x0.
/// @return The badge token URI (same format as ERC721).
function badgeTokenURI(bytes32 uid) external view returns (string memory);
/// @notice Returns true if the user has one or more of this badge.
/// @param user The user's wallet address.
/// @return True if the user has one or more of this badge.
function hasBadge(address user) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {Attestation} from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
interface IScrollBadgeResolver {
/**
*
* Events *
*
*/
/// @dev Emitted when a new badge is issued.
/// @param uid The UID of the new badge attestation.
event IssueBadge(bytes32 indexed uid);
/// @dev Emitted when a badge is revoked.
/// @param uid The UID of the revoked badge attestation.
event RevokeBadge(bytes32 indexed uid);
/// @dev Emitted when the auto-attach status of a badge is updated.
/// @param badge The address of the badge contract.
/// @param enable Auto-attach was enabled if true, disabled if false.
event UpdateAutoAttachWhitelist(address indexed badge, bool indexed enable);
/**
*
* Public View Functions *
*
*/
/// @notice Return the Scroll badge attestation schema.
/// @return The GUID of the Scroll badge attestation schema.
function schema() external returns (bytes32);
/// @notice The profile registry contract.
/// @return The address of the profile registry.
function registry() external returns (address);
/// @notice The global EAS contract.
/// @return The address of the global EAS contract.
function eas() external returns (address);
/// @notice Validate and return a Scroll badge attestation.
/// @param uid The attestation UID.
/// @return The attestation.
function getAndValidateBadge(bytes32 uid) external view returns (Attestation memory);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"resolver_","type":"address"},{"internalType":"uint8","name":"variant_","type":"uint8"},{"internalType":"string","name":"_baseTokenURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"uid","type":"bytes32"}],"name":"AttestationBadgeMismatch","type":"error"},{"inputs":[],"name":"SingletonBadge","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"uid","type":"bytes32"}],"name":"IssueBadge","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":true,"internalType":"bytes32","name":"uid","type":"bytes32"}],"name":"RevokeBadge","type":"event"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"badgeTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"uid","type":"bytes32"}],"name":"getAndValidateBadge","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":"hasBadge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAttester","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"attestation","type":"tuple"}],"name":"issueBadge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"attestation","type":"tuple"}],"name":"revokeBadge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"toggleAttester","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"variant","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002711380380620027118339818101604052810190620000379190620003b8565b82620000586200004c620000b660201b60201c565b620000be60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508160ff1660a08160ff16815250508060039081620000ac91906200067e565b5050505062000765565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001c38262000196565b9050919050565b620001d581620001b6565b8114620001e157600080fd5b50565b600081519050620001f581620001ca565b92915050565b600060ff82169050919050565b6200021381620001fb565b81146200021f57600080fd5b50565b600081519050620002338162000208565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200028e8262000243565b810181811067ffffffffffffffff82111715620002b057620002af62000254565b5b80604052505050565b6000620002c562000182565b9050620002d3828262000283565b919050565b600067ffffffffffffffff821115620002f657620002f562000254565b5b620003018262000243565b9050602081019050919050565b60005b838110156200032e57808201518184015260208101905062000311565b60008484015250505050565b6000620003516200034b84620002d8565b620002b9565b90508281526020810184848401111562000370576200036f6200023e565b5b6200037d8482856200030e565b509392505050565b600082601f8301126200039d576200039c62000239565b5b8151620003af8482602086016200033a565b91505092915050565b600080600060608486031215620003d457620003d36200018c565b5b6000620003e486828701620001e4565b9350506020620003f78682870162000222565b925050604084015167ffffffffffffffff8111156200041b576200041a62000191565b5b620004298682870162000385565b9150509250925092565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200048657607f821691505b6020821081036200049c576200049b6200043e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004c7565b620005128683620004c7565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200055f6200055962000553846200052a565b62000534565b6200052a565b9050919050565b6000819050919050565b6200057b836200053e565b620005936200058a8262000566565b848454620004d4565b825550505050565b600090565b620005aa6200059b565b620005b781848462000570565b505050565b5b81811015620005df57620005d3600082620005a0565b600181019050620005bd565b5050565b601f8211156200062e57620005f881620004a2565b6200060384620004b7565b8101602085101562000613578190505b6200062b6200062285620004b7565b830182620005bc565b50505b505050565b600082821c905092915050565b6000620006536000198460080262000633565b1980831691505092915050565b60006200066e838362000640565b9150826002028217905092915050565b620006898262000433565b67ffffffffffffffff811115620006a557620006a462000254565b5b620006b182546200046d565b620006be828285620005e3565b600060209050601f831160018114620006f65760008415620006e1578287015190505b620006ed858262000660565b8655506200075d565b601f1984166200070686620004a2565b60005b82811015620007305784890151825560018201915060208501945060208101905062000709565b868310156200075057848901516200074c601f89168262000640565b8355505b6001600288020188555050505b505050505050565b60805160a051611f6a620007a76000396000818161030b01526103990152600081816102e701528181610465015281816105ad01526107b40152611f6a6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638298b0301161008c578063b6ebe53911610066578063b6ebe5391461024b578063d547cfb71461027b578063d753a63d14610299578063f2fde38b146102c9576100ea565b80638298b030146101cd5780638c6f12f0146101fd5780638da5cb5b1461022d576100ea565b806324830563116100c8578063248305631461014757806330176e13146101775780635e50864f14610193578063715018a6146101c3576100ea565b806304f3bcec146100ef57806305bc64eb1461010d5780630ee489481461012b575b600080fd5b6100f76102e5565b6040516101049190611016565b60405180910390f35b610115610309565b604051610122919061104d565b60405180910390f35b610145600480360381019061014091906110e0565b61032d565b005b610161600480360381019061015c9190611156565b610390565b60405161016e9190611213565b60405180910390f35b610191600480360381019061018c919061136a565b6103e7565b005b6101ad60048036038101906101a891906113b3565b610402565b6040516101ba91906113ef565b60405180910390f35b6101cb61044d565b005b6101e760048036038101906101e2919061142f565b610461565b6040516101f491906113ef565b60405180910390f35b61021760048036038101906102129190611156565b6105a1565b60405161022491906115f7565b60405180910390f35b6102356106d9565b6040516102429190611016565b60405180910390f35b610265600480360381019061026091906113b3565b610702565b60405161027291906113ef565b60405180910390f35b610283610722565b6040516102909190611213565b60405180910390f35b6102b360048036038101906102ae919061142f565b6107b0565b6040516102c091906113ef565b60405180910390f35b6102e360048036038101906102de91906113b3565b6108f0565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b610335610973565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b606060036103c07f000000000000000000000000000000000000000000000000000000000000000060ff166109f1565b6040516020016103d1929190611799565b6040516020818303038152906040529050919050565b6103ef610973565b80600390816103fe9190611969565b5050565b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054119050919050565b610455610973565b61045f6000610abf565b565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104e8576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104f182610b83565b6104fe576000905061059c565b60018060008460c001602081019061051691906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461055f9190611a6a565b9250508190555081600001357f504e4727721de18c6bf7f66448a6ff6da00aa4b1f00b6034e71723ae7ce6373a60405160405180910390a2600190505b919050565b6105a9610f2d565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638c6f12f0846040518263ffffffff1660e01b81526004016106049190611aad565b600060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061064a9190611cf0565b9050600061065c826101200151610b95565b5090503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106cf57836040517fb923d2610000000000000000000000000000000000000000000000000000000081526004016106c69190611aad565b60405180910390fd5b8192505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915054906101000a900460ff1681565b6003805461072f90611648565b80601f016020809104026020016040519081016040528092919081815260200182805461075b90611648565b80156107a85780601f1061077d576101008083540402835291602001916107a8565b820191906000526020600020905b81548152906001019060200180831161078b57829003601f168201915b505050505081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610837576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084082610bb6565b61084d57600090506108eb565b60018060008460c001602081019061086591906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ae9190611d39565b9250508190555081600001357fa0785ec0b9bf31a5475d33c716fb9f500f0ea0bb9e4bc10ec39d5db763c1da1560405160405180910390a2600190505b919050565b6108f8610973565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095e90611ddf565b60405180910390fd5b61097081610abf565b50565b61097b610bc8565b73ffffffffffffffffffffffffffffffffffffffff166109996106d9565b73ffffffffffffffffffffffffffffffffffffffff16146109ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e690611e4b565b60405180910390fd5b565b606060006001610a0084610bd0565b01905060008167ffffffffffffffff811115610a1f57610a1e61123f565b5b6040519080825280601f01601f191660200182016040528015610a515781602001600182028036833780820191505090505b509050600082602001820190505b600115610ab4578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610aa857610aa7611e6b565b5b04945060008503610a5f575b819350505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000610b8e82610d23565b9050919050565b6000606082806020019051810190610bad9190611ed8565b91509150915091565b6000610bc182610d35565b9050919050565b600033905090565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610c2e577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381610c2457610c23611e6b565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310610c6b576d04ee2d6d415b85acef81000000008381610c6157610c60611e6b565b5b0492506020810190505b662386f26fc100008310610c9a57662386f26fc100008381610c9057610c8f611e6b565b5b0492506010810190505b6305f5e1008310610cc3576305f5e1008381610cb957610cb8611e6b565b5b0492506008810190505b6127108310610ce8576127108381610cde57610cdd611e6b565b5b0492506004810190505b60648310610d0b5760648381610d0157610d00611e6b565b5b0492506002810190505b600a8310610d1a576001810190505b80915050919050565b6000610d2e82610da9565b9050919050565b6000610d4082610e60565b610d4d5760009050610da4565b610d688260c0016020810190610d6391906113b3565b610402565b15610d9f576040517f18b2623200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b6000610db482610f17565b610dc15760009050610e5b565b600260008360e0016020810190610dd891906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610e56576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b6000610e6b82610f22565b610e785760009050610f12565b600260008360e0016020810190610e8f91906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610f0d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b600060019050919050565b600060019050919050565b6040518061014001604052806000801916815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061100082610fd5565b9050919050565b61101081610ff5565b82525050565b600060208201905061102b6000830184611007565b92915050565b600060ff82169050919050565b61104781611031565b82525050565b6000602082019050611062600083018461103e565b92915050565b6000604051905090565b600080fd5b600080fd5b61108581610ff5565b811461109057600080fd5b50565b6000813590506110a28161107c565b92915050565b60008115159050919050565b6110bd816110a8565b81146110c857600080fd5b50565b6000813590506110da816110b4565b92915050565b600080604083850312156110f7576110f6611072565b5b600061110585828601611093565b9250506020611116858286016110cb565b9150509250929050565b6000819050919050565b61113381611120565b811461113e57600080fd5b50565b6000813590506111508161112a565b92915050565b60006020828403121561116c5761116b611072565b5b600061117a84828501611141565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156111bd5780820151818401526020810190506111a2565b60008484015250505050565b6000601f19601f8301169050919050565b60006111e582611183565b6111ef818561118e565b93506111ff81856020860161119f565b611208816111c9565b840191505092915050565b6000602082019050818103600083015261122d81846111da565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611277826111c9565b810181811067ffffffffffffffff821117156112965761129561123f565b5b80604052505050565b60006112a9611068565b90506112b5828261126e565b919050565b600067ffffffffffffffff8211156112d5576112d461123f565b5b6112de826111c9565b9050602081019050919050565b82818337600083830152505050565b600061130d611308846112ba565b61129f565b9050828152602081018484840111156113295761132861123a565b5b6113348482856112eb565b509392505050565b600082601f83011261135157611350611235565b5b81356113618482602086016112fa565b91505092915050565b6000602082840312156113805761137f611072565b5b600082013567ffffffffffffffff81111561139e5761139d611077565b5b6113aa8482850161133c565b91505092915050565b6000602082840312156113c9576113c8611072565b5b60006113d784828501611093565b91505092915050565b6113e9816110a8565b82525050565b600060208201905061140460008301846113e0565b92915050565b600080fd5b600061014082840312156114265761142561140a565b5b81905092915050565b60006020828403121561144557611444611072565b5b600082013567ffffffffffffffff81111561146357611462611077565b5b61146f8482850161140f565b91505092915050565b61148181611120565b82525050565b600067ffffffffffffffff82169050919050565b6114a481611487565b82525050565b6114b381610ff5565b82525050565b6114c2816110a8565b82525050565b600081519050919050565b600082825260208201905092915050565b60006114ef826114c8565b6114f981856114d3565b935061150981856020860161119f565b611512816111c9565b840191505092915050565b6000610140830160008301516115366000860182611478565b5060208301516115496020860182611478565b50604083015161155c604086018261149b565b50606083015161156f606086018261149b565b506080830151611582608086018261149b565b5060a083015161159560a0860182611478565b5060c08301516115a860c08601826114aa565b5060e08301516115bb60e08601826114aa565b506101008301516115d06101008601826114b9565b506101208301518482036101208601526115ea82826114e4565b9150508091505092915050565b60006020820190508181036000830152611611818461151d565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061166057607f821691505b60208210810361167357611672611619565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b600081546116a681611648565b6116b08186611679565b945060018216600081146116cb57600181146116e057611713565b60ff1983168652811515820286019350611713565b6116e985611684565b60005b8381101561170b578154818901526001820191506020810190506116ec565b838801955050505b50505092915050565b600061172782611183565b6117318185611679565b935061174181856020860161119f565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000611783600583611679565b915061178e8261174d565b600582019050919050565b60006117a58285611699565b91506117b1828461171c565b91506117bc82611776565b91508190509392505050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026118157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826117d8565b61181f86836117d8565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061186661186161185c84611837565b611841565b611837565b9050919050565b6000819050919050565b6118808361184b565b61189461188c8261186d565b8484546117e5565b825550505050565b600090565b6118a961189c565b6118b4818484611877565b505050565b5b818110156118d8576118cd6000826118a1565b6001810190506118ba565b5050565b601f82111561191d576118ee81611684565b6118f7846117c8565b81016020851015611906578190505b61191a611912856117c8565b8301826118b9565b50505b505050565b600082821c905092915050565b600061194060001984600802611922565b1980831691505092915050565b6000611959838361192f565b9150826002028217905092915050565b61197282611183565b67ffffffffffffffff81111561198b5761198a61123f565b5b6119958254611648565b6119a08282856118dc565b600060209050601f8311600181146119d357600084156119c1578287015190505b6119cb858261194d565b865550611a33565b601f1984166119e186611684565b60005b82811015611a09578489015182556001820191506020850194506020810190506119e4565b86831015611a265784890151611a22601f89168261192f565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611a7582611837565b9150611a8083611837565b9250828203905081811115611a9857611a97611a3b565b5b92915050565b611aa781611120565b82525050565b6000602082019050611ac26000830184611a9e565b92915050565b600080fd5b600080fd5b600081519050611ae18161112a565b92915050565b611af081611487565b8114611afb57600080fd5b50565b600081519050611b0d81611ae7565b92915050565b600081519050611b228161107c565b92915050565b600081519050611b37816110b4565b92915050565b600067ffffffffffffffff821115611b5857611b5761123f565b5b611b61826111c9565b9050602081019050919050565b6000611b81611b7c84611b3d565b61129f565b905082815260208101848484011115611b9d57611b9c61123a565b5b611ba884828561119f565b509392505050565b600082601f830112611bc557611bc4611235565b5b8151611bd5848260208601611b6e565b91505092915050565b60006101408284031215611bf557611bf4611ac8565b5b611c0061014061129f565b90506000611c1084828501611ad2565b6000830152506020611c2484828501611ad2565b6020830152506040611c3884828501611afe565b6040830152506060611c4c84828501611afe565b6060830152506080611c6084828501611afe565b60808301525060a0611c7484828501611ad2565b60a08301525060c0611c8884828501611b13565b60c08301525060e0611c9c84828501611b13565b60e083015250610100611cb184828501611b28565b6101008301525061012082015167ffffffffffffffff811115611cd757611cd6611acd565b5b611ce384828501611bb0565b6101208301525092915050565b600060208284031215611d0657611d05611072565b5b600082015167ffffffffffffffff811115611d2457611d23611077565b5b611d3084828501611bde565b91505092915050565b6000611d4482611837565b9150611d4f83611837565b9250828201905080821115611d6757611d66611a3b565b5b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611dc960268361118e565b9150611dd482611d6d565b604082019050919050565b60006020820190508181036000830152611df881611dbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611e3560208361118e565b9150611e4082611dff565b602082019050919050565b60006020820190508181036000830152611e6481611e28565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611ea582610fd5565b9050919050565b611eb581611e9a565b8114611ec057600080fd5b50565b600081519050611ed281611eac565b92915050565b60008060408385031215611eef57611eee611072565b5b6000611efd85828601611ec3565b925050602083015167ffffffffffffffff811115611f1e57611f1d611077565b5b611f2a85828601611bb0565b915050925092905056fea26469706673582212201c4f6470e6d87abb1bf22ae263df0fdea40a0eb2bfecf3bd9ee97da1c7145dcf64736f6c634300081300330000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f7777772e746f61737465722e66696e616e63652f6173736574732f7363726f6c6c2d62616467652f00000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638298b0301161008c578063b6ebe53911610066578063b6ebe5391461024b578063d547cfb71461027b578063d753a63d14610299578063f2fde38b146102c9576100ea565b80638298b030146101cd5780638c6f12f0146101fd5780638da5cb5b1461022d576100ea565b806324830563116100c8578063248305631461014757806330176e13146101775780635e50864f14610193578063715018a6146101c3576100ea565b806304f3bcec146100ef57806305bc64eb1461010d5780630ee489481461012b575b600080fd5b6100f76102e5565b6040516101049190611016565b60405180910390f35b610115610309565b604051610122919061104d565b60405180910390f35b610145600480360381019061014091906110e0565b61032d565b005b610161600480360381019061015c9190611156565b610390565b60405161016e9190611213565b60405180910390f35b610191600480360381019061018c919061136a565b6103e7565b005b6101ad60048036038101906101a891906113b3565b610402565b6040516101ba91906113ef565b60405180910390f35b6101cb61044d565b005b6101e760048036038101906101e2919061142f565b610461565b6040516101f491906113ef565b60405180910390f35b61021760048036038101906102129190611156565b6105a1565b60405161022491906115f7565b60405180910390f35b6102356106d9565b6040516102429190611016565b60405180910390f35b610265600480360381019061026091906113b3565b610702565b60405161027291906113ef565b60405180910390f35b610283610722565b6040516102909190611213565b60405180910390f35b6102b360048036038101906102ae919061142f565b6107b0565b6040516102c091906113ef565b60405180910390f35b6102e360048036038101906102de91906113b3565b6108f0565b005b7f0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011381565b7f000000000000000000000000000000000000000000000000000000000000000381565b610335610973565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b606060036103c07f000000000000000000000000000000000000000000000000000000000000000360ff166109f1565b6040516020016103d1929190611799565b6040516020818303038152906040529050919050565b6103ef610973565b80600390816103fe9190611969565b5050565b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054119050919050565b610455610973565b61045f6000610abf565b565b60007f0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104e8576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104f182610b83565b6104fe576000905061059c565b60018060008460c001602081019061051691906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461055f9190611a6a565b9250508190555081600001357f504e4727721de18c6bf7f66448a6ff6da00aa4b1f00b6034e71723ae7ce6373a60405160405180910390a2600190505b919050565b6105a9610f2d565b60007f0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011373ffffffffffffffffffffffffffffffffffffffff16638c6f12f0846040518263ffffffff1660e01b81526004016106049190611aad565b600060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061064a9190611cf0565b9050600061065c826101200151610b95565b5090503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106cf57836040517fb923d2610000000000000000000000000000000000000000000000000000000081526004016106c69190611aad565b60405180910390fd5b8192505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915054906101000a900460ff1681565b6003805461072f90611648565b80601f016020809104026020016040519081016040528092919081815260200182805461075b90611648565b80156107a85780601f1061077d576101008083540402835291602001916107a8565b820191906000526020600020905b81548152906001019060200180831161078b57829003601f168201915b505050505081565b60007f0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610837576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084082610bb6565b61084d57600090506108eb565b60018060008460c001602081019061086591906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ae9190611d39565b9250508190555081600001357fa0785ec0b9bf31a5475d33c716fb9f500f0ea0bb9e4bc10ec39d5db763c1da1560405160405180910390a2600190505b919050565b6108f8610973565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095e90611ddf565b60405180910390fd5b61097081610abf565b50565b61097b610bc8565b73ffffffffffffffffffffffffffffffffffffffff166109996106d9565b73ffffffffffffffffffffffffffffffffffffffff16146109ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e690611e4b565b60405180910390fd5b565b606060006001610a0084610bd0565b01905060008167ffffffffffffffff811115610a1f57610a1e61123f565b5b6040519080825280601f01601f191660200182016040528015610a515781602001600182028036833780820191505090505b509050600082602001820190505b600115610ab4578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610aa857610aa7611e6b565b5b04945060008503610a5f575b819350505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000610b8e82610d23565b9050919050565b6000606082806020019051810190610bad9190611ed8565b91509150915091565b6000610bc182610d35565b9050919050565b600033905090565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610c2e577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381610c2457610c23611e6b565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310610c6b576d04ee2d6d415b85acef81000000008381610c6157610c60611e6b565b5b0492506020810190505b662386f26fc100008310610c9a57662386f26fc100008381610c9057610c8f611e6b565b5b0492506010810190505b6305f5e1008310610cc3576305f5e1008381610cb957610cb8611e6b565b5b0492506008810190505b6127108310610ce8576127108381610cde57610cdd611e6b565b5b0492506004810190505b60648310610d0b5760648381610d0157610d00611e6b565b5b0492506002810190505b600a8310610d1a576001810190505b80915050919050565b6000610d2e82610da9565b9050919050565b6000610d4082610e60565b610d4d5760009050610da4565b610d688260c0016020810190610d6391906113b3565b610402565b15610d9f576040517f18b2623200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b6000610db482610f17565b610dc15760009050610e5b565b600260008360e0016020810190610dd891906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610e56576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b6000610e6b82610f22565b610e785760009050610f12565b600260008360e0016020810190610e8f91906113b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610f0d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600190505b919050565b600060019050919050565b600060019050919050565b6040518061014001604052806000801916815260200160008019168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061100082610fd5565b9050919050565b61101081610ff5565b82525050565b600060208201905061102b6000830184611007565b92915050565b600060ff82169050919050565b61104781611031565b82525050565b6000602082019050611062600083018461103e565b92915050565b6000604051905090565b600080fd5b600080fd5b61108581610ff5565b811461109057600080fd5b50565b6000813590506110a28161107c565b92915050565b60008115159050919050565b6110bd816110a8565b81146110c857600080fd5b50565b6000813590506110da816110b4565b92915050565b600080604083850312156110f7576110f6611072565b5b600061110585828601611093565b9250506020611116858286016110cb565b9150509250929050565b6000819050919050565b61113381611120565b811461113e57600080fd5b50565b6000813590506111508161112a565b92915050565b60006020828403121561116c5761116b611072565b5b600061117a84828501611141565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156111bd5780820151818401526020810190506111a2565b60008484015250505050565b6000601f19601f8301169050919050565b60006111e582611183565b6111ef818561118e565b93506111ff81856020860161119f565b611208816111c9565b840191505092915050565b6000602082019050818103600083015261122d81846111da565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611277826111c9565b810181811067ffffffffffffffff821117156112965761129561123f565b5b80604052505050565b60006112a9611068565b90506112b5828261126e565b919050565b600067ffffffffffffffff8211156112d5576112d461123f565b5b6112de826111c9565b9050602081019050919050565b82818337600083830152505050565b600061130d611308846112ba565b61129f565b9050828152602081018484840111156113295761132861123a565b5b6113348482856112eb565b509392505050565b600082601f83011261135157611350611235565b5b81356113618482602086016112fa565b91505092915050565b6000602082840312156113805761137f611072565b5b600082013567ffffffffffffffff81111561139e5761139d611077565b5b6113aa8482850161133c565b91505092915050565b6000602082840312156113c9576113c8611072565b5b60006113d784828501611093565b91505092915050565b6113e9816110a8565b82525050565b600060208201905061140460008301846113e0565b92915050565b600080fd5b600061014082840312156114265761142561140a565b5b81905092915050565b60006020828403121561144557611444611072565b5b600082013567ffffffffffffffff81111561146357611462611077565b5b61146f8482850161140f565b91505092915050565b61148181611120565b82525050565b600067ffffffffffffffff82169050919050565b6114a481611487565b82525050565b6114b381610ff5565b82525050565b6114c2816110a8565b82525050565b600081519050919050565b600082825260208201905092915050565b60006114ef826114c8565b6114f981856114d3565b935061150981856020860161119f565b611512816111c9565b840191505092915050565b6000610140830160008301516115366000860182611478565b5060208301516115496020860182611478565b50604083015161155c604086018261149b565b50606083015161156f606086018261149b565b506080830151611582608086018261149b565b5060a083015161159560a0860182611478565b5060c08301516115a860c08601826114aa565b5060e08301516115bb60e08601826114aa565b506101008301516115d06101008601826114b9565b506101208301518482036101208601526115ea82826114e4565b9150508091505092915050565b60006020820190508181036000830152611611818461151d565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061166057607f821691505b60208210810361167357611672611619565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b600081546116a681611648565b6116b08186611679565b945060018216600081146116cb57600181146116e057611713565b60ff1983168652811515820286019350611713565b6116e985611684565b60005b8381101561170b578154818901526001820191506020810190506116ec565b838801955050505b50505092915050565b600061172782611183565b6117318185611679565b935061174181856020860161119f565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000611783600583611679565b915061178e8261174d565b600582019050919050565b60006117a58285611699565b91506117b1828461171c565b91506117bc82611776565b91508190509392505050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026118157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826117d8565b61181f86836117d8565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061186661186161185c84611837565b611841565b611837565b9050919050565b6000819050919050565b6118808361184b565b61189461188c8261186d565b8484546117e5565b825550505050565b600090565b6118a961189c565b6118b4818484611877565b505050565b5b818110156118d8576118cd6000826118a1565b6001810190506118ba565b5050565b601f82111561191d576118ee81611684565b6118f7846117c8565b81016020851015611906578190505b61191a611912856117c8565b8301826118b9565b50505b505050565b600082821c905092915050565b600061194060001984600802611922565b1980831691505092915050565b6000611959838361192f565b9150826002028217905092915050565b61197282611183565b67ffffffffffffffff81111561198b5761198a61123f565b5b6119958254611648565b6119a08282856118dc565b600060209050601f8311600181146119d357600084156119c1578287015190505b6119cb858261194d565b865550611a33565b601f1984166119e186611684565b60005b82811015611a09578489015182556001820191506020850194506020810190506119e4565b86831015611a265784890151611a22601f89168261192f565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611a7582611837565b9150611a8083611837565b9250828203905081811115611a9857611a97611a3b565b5b92915050565b611aa781611120565b82525050565b6000602082019050611ac26000830184611a9e565b92915050565b600080fd5b600080fd5b600081519050611ae18161112a565b92915050565b611af081611487565b8114611afb57600080fd5b50565b600081519050611b0d81611ae7565b92915050565b600081519050611b228161107c565b92915050565b600081519050611b37816110b4565b92915050565b600067ffffffffffffffff821115611b5857611b5761123f565b5b611b61826111c9565b9050602081019050919050565b6000611b81611b7c84611b3d565b61129f565b905082815260208101848484011115611b9d57611b9c61123a565b5b611ba884828561119f565b509392505050565b600082601f830112611bc557611bc4611235565b5b8151611bd5848260208601611b6e565b91505092915050565b60006101408284031215611bf557611bf4611ac8565b5b611c0061014061129f565b90506000611c1084828501611ad2565b6000830152506020611c2484828501611ad2565b6020830152506040611c3884828501611afe565b6040830152506060611c4c84828501611afe565b6060830152506080611c6084828501611afe565b60808301525060a0611c7484828501611ad2565b60a08301525060c0611c8884828501611b13565b60c08301525060e0611c9c84828501611b13565b60e083015250610100611cb184828501611b28565b6101008301525061012082015167ffffffffffffffff811115611cd757611cd6611acd565b5b611ce384828501611bb0565b6101208301525092915050565b600060208284031215611d0657611d05611072565b5b600082015167ffffffffffffffff811115611d2457611d23611077565b5b611d3084828501611bde565b91505092915050565b6000611d4482611837565b9150611d4f83611837565b9250828201905080821115611d6757611d66611a3b565b5b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611dc960268361118e565b9150611dd482611d6d565b604082019050919050565b60006020820190508181036000830152611df881611dbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611e3560208361118e565b9150611e4082611dff565b602082019050919050565b60006020820190508181036000830152611e6481611e28565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611ea582610fd5565b9050919050565b611eb581611e9a565b8114611ec057600080fd5b50565b600081519050611ed281611eac565b92915050565b60008060408385031215611eef57611eee611072565b5b6000611efd85828601611ec3565b925050602083015167ffffffffffffffff811115611f1e57611f1d611077565b5b611f2a85828601611bb0565b915050925092905056fea26469706673582212201c4f6470e6d87abb1bf22ae263df0fdea40a0eb2bfecf3bd9ee97da1c7145dcf64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec011300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f7777772e746f61737465722e66696e616e63652f6173736574732f7363726f6c6c2d62616467652f00000000000000000000000000000000
-----Decoded View---------------
Arg [0] : resolver_ (address): 0x4560FECd62B14A463bE44D40fE5Cfd595eEc0113
Arg [1] : variant_ (uint8): 3
Arg [2] : _baseTokenURI (string): https://www.toaster.finance/assets/scroll-badge/
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000004560fecd62b14a463be44d40fe5cfd595eec0113
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000030
Arg [4] : 68747470733a2f2f7777772e746f61737465722e66696e616e63652f61737365
Arg [5] : 74732f7363726f6c6c2d62616467652f00000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
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.